Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file order_list.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216typet={mutabletag:int;mutableprev:t;mutablenext:t;counter:intref;}letaveragexy=(xlandy)+(xlxory)/2letcurr_indext=t.tagletrecsentinel={tag=0;prev=sentinel;next=sentinel;counter=ref0}letis_firstt=t.prev==tletis_lastt=t==t.nextletis_validt=t.next!=sentinelletprev_indext=ifis_firsttthenmin_intelset.prev.tagletnext_indext=ifis_lasttthenmax_intelset.next.tagletcheckt=assert(is_validt);assert(is_validt.prev);assert(is_validt.next);assert(t==t.prev||t.prev.next==t);assert(t==t.next||t.next.prev==t);ift.next!=tthenassert(t.next.tag>t.tag);ift.prev!=tthenassert(t.prev.tag<t.tag)letconsistent_=()letconsistents__=()(*let rec consistents t = function
| 0 -> ()
| 1 -> consistent t
| n ->
consistent t;
assert (t.next != t);
consistents t (n - 1)*)letroot()=letrect={prev=t;next=t;tag=0;counter=ref1}inconsistentt;tletforgett=ifis_validtthenbeginlet{prev;next;counter;_}=tinifis_firsttthennext.prev<-nextelseifis_lasttthenprev.next<-prevelse(prev.next<-next;next.prev<-prev;);decrcounter;t.next<-sentinel;t.prev<-sentinel;consistentprev;consistentnext;assert(not(is_validt));endletsame_ordert1t2=is_validt1&&is_validt2&&t1.counter==t2.counterletcomparet1t2=assert(same_ordert1t2);comparet1.tagt2.tagletcardinalt=ifis_validtthen!(t.counter)else0letuint_size=Sys.word_size-2letpow=2.0**floatuint_sizeletinv=1.0/.floatuint_sizeletoptimal_tcount=(pow/.floatcount)**invletfind_spann=lett=optimal_t!(n.counter)inletcount=ref1andleft=refnandright=refnandtag=n.tagandlow=refn.tagandhigh=refn.tagandbit=ref1andthresh=ref1.0inwhile!bit>0&&(float!count>=float!bit*.!thresh)doletto_left=(tagland!bit)<>0inifto_leftthenbeginlow:=!lowlxor!bit;while!left.tag>!low&¬(is_first!left)doleft:=!left.prev;incrcount;doneendelsebeginhigh:=!highlxor!bit;while!right.tag<!high&¬(is_last!right)doright:=!right.next;incrcount;doneend;bit:=!bitlsl1;thresh:=!thresh/.t;done;!left,!low,(!bitlsr1),!countletrecrelabel_span_bigrootsteptag=function|1->root.tag<-tag;assert(tag<next_indexroot||is_lastroot)|n->root.tag<-tag;assert(tag>prev_indexroot);relabel_span_bigroot.nextstep(tag+step)(n-1)letrecrelabel_span_smallnoderootslacktag=function|1->root.tag<-tag;assert(tag<next_indexroot||is_lastroot)|n->root.tag<-tag;(*Printf.eprintf "assert (%d > %d); slack = %d\n"
tag (prev_index root) slack;*)assert(tag>prev_indexroot);relabel_span_smallnoderoot.nextslack(tag+ifnode==rootthenslack+1else1)(n-1)letrelabelnode=letroot,tag,range,count=find_spannodeinletstep=range/countin(*Printf.eprintf "range = %d, count = %d\n" range count;*)ifstep<=1then(assert(range>=count);relabel_span_smallnoderoot(range-count)(tag+1)count)elserelabel_span_bigrootstep(tag+step)count;consistentsrootcountletaftert=assert(is_validt);lettag=average(curr_indext)(next_indext)in(* IMPORTANT
Allocation must be done before reading t.prev/t.next.
It might trigger a garbage collection which can invalidate the
linked list (e.g if used through Order_managed).
*)lett'={prev=t;next=t;tag;counter=t.counter}inlet{next;counter;_}=tinift==nextthent'.next<-t'else(t'.next<-next;next.prev<-t');t.next<-t';incrcounter;ift'.tag=prev_indext'thenrelabelt';consistentt;consistentt';t'letbeforet=assert(is_validt);lettag=average(prev_indext)(curr_indext)in(* IMPORTANT
Allocation must be done before reading t.prev/t.next.
It might trigger a garbage collection which can invalidate the
linked list (e.g if used through Order_managed).
*)lett'={prev=t;next=t;tag;counter=t.counter}inlet{prev;counter;_}=tinift==prevthent'.prev<-t'else(t'.prev<-prev;prev.next<-t');t.prev<-t';incrcounter;ift'.tag=prev_indext'thenrelabelt';consistentt;consistentt';t'letunsafe_nextt=t.nextletunsafe_prevt=t.prevletunsafe_checktmsg=tryifis_validtthenchecktelsebeginassert(t.prev==sentinel);assert(t.next==sentinel);endwithAssert_failure(file,line,col)->raise(Assert_failure(msg^": "^file,line,col))