12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091# 1 "src/base/misc/owl_utils_heap.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2020 Liang Wang <liang.wang@cl.cam.ac.uk>
*)(* A naive implementation of a min-heap for Owl's internal use. *)type'at={mutableused:int;mutabledata:'aarray;cmp:'a->'a->int}letleft_sonpos=(poslsl1)+1letright_sonpos=(poslsl1)+2letparentpos=(pos-1)lsr1(* can't set an initial size without knowing the type *)letmakecmp={used=0;data=[||];cmp}letmake_int?(initial_size=0)cmp={used=0;data=Array.makeinitial_size0;cmp}letmake_float?(initial_size=0)cmp={used=0;data=Array.makeinitial_size0.;cmp}letsize_arrheap=Array.lengthheap.dataletextend_sizeheap=heap.data<-Array.(appendheap.data(copyheap.data))letsizeheap=heap.usedletpush({used;cmp;_}asheap)x=ifsize_arrheap=0then(heap.data<-[|x|];heap.used<-1)else(ifsize_arrheap<=usedthenextend_sizeheap;(* insert x at the end and swap it with its parent if x is smaller *)letpos=refusedinletpar=ref(parent!pos)inwhile!pos>0&&cmpxheap.data.(!par)<0doheap.data.(!pos)<-heap.data.(!par);pos:=!par;par:=parent!posdone;heap.used<-used+1;heap.data.(!pos)<-x)letpop({data;cmp;_}asheap)=matchheap.usedwith|0->invalid_arg"owl_utils_heap: can't pop an element from an empty heap"|_->letx=data.(0)in(* replace the first element with the last one and swap it with its
* smallest son *)heap.used<-heap.used-1;data.(0)<-data.(heap.used);letpos=ref0inletagain=reftrueinwhile!againdoletsmall=ref!posinletleft=left_son!posandright=right_son!posinifleft<heap.used&&cmpdata.(left)data.(!small)<0thensmall:=left;ifright<heap.used&&cmpdata.(right)data.(!small)<0thensmall:=right;if!pos=!smallthenagain:=falseelse(lettmp=data.(!pos)indata.(!pos)<-data.(!small);data.(!small)<-tmp;pos:=!small)done;xletpeekheap=matchheap.usedwith|0->invalid_arg"owl_utils_heap: can't peek at an empty heap"|_->heap.data.(0)letis_emptyheap=heap.used=0letto_arrayheap=Array.subheap.data0heap.used