123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106# 1 "src/base/misc/owl_utils_heap.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2019 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<=usedthen(extend_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(!pos);done;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)<0then(small:=left);ifright<heap.used&&cmpdata.(right)data.(!small)<0then(small:=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