123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164(*
* Copyright (c) 2019-2021 Craig Ferguson <craig@tarides.com>
* Copyright (c) 2018-2022 Tarides <contact@tarides.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)(* Extensions to the default namespace, opened throughout the Irmin codebase. *)typeread=Perms.readtypewrite=Perms.writetyperead_write=Perms.read_write(** {2 Lwt syntax} *)includeLwt.Syntaxlet(>>=)=Lwt.Infix.(>>=)let(>|=)=Lwt.Infix.(>|=)(** {2 Dependency extensions} *)moduleOption=structincludeOption(** @closed *)letof_result=functionOkx->Somex|Error_->Noneletmightf=functionSomex->fx|None->Ok()endmoduleList=structincludeList(** @closed *)letrecis_longer_than:typea.int->alist->bool=funlenl->iflen<0thentrueelsematchlwith[]->false|_::tl->is_longer_than(len-1)tlletmapfl=letrecauxacc=function|[]->acc[]|h::t->(aux[@tailcall])(funt'->acc(fh::t'))tinaux(funx->x)lletconcatl=letrecauxacccurrl=match(curr,l)with|[],[]->List.revacc|[],[l]->List.rev_appendaccl|[],h::t->(aux[@tailcall])accht|h::t,l->(aux[@tailcall])(h::acc)tlinaux[][]l(* For compatibility with versions older than ocaml.4.11.0 *)letconcat_mapfl=letrecauxfacc=function|[]->revacc|x::l->letxs=fxinauxf(rev_appendxsacc)linauxf[]lletrecmem:typea.equal:(a->a->bool)->a->at->bool=fun~equaly->function|[]->false|x::xs->equalxy||mem~equalyxsletrecrev_append_map:typeab.(a->b)->alist->blist->blist=funfxsys->matchxswith[]->ys|x::xs->rev_append_mapfxs(fx::ys)letinsert_exn:typea.alist->int->a->alist=funlidxv->(* [list_insert l 0 v] is [v :: l] *)assert(idx>=0);letrecauxliacc=ifi=0thenList.rev_appendacc(v::l)elsematchlwith|[]->failwith"list_insert: input list too short"|hd::tl->auxtl(i-1)(hd::acc)inauxlidx[]endmoduleMtime=structincludeMtimeletspan_to_sspan=Mtime.Span.to_float_nsspan*.1e-9letspan_to_usspan=Mtime.Span.to_float_nsspan*.1e-3endmoduleSeq=structincludeSeq(** @closed *)letrecdrop:typea.int->at->at=funnl()->matchl()with|l'whenn=0->l'|Nil->Nil|Cons(_,l')->drop(n-1)l'()letexists:typea.(a->bool)->aSeq.t->bool=funfs->letrecauxs=matchs()withSeq.Nil->false|Seq.Cons(v,s)->fv||auxsinauxsletrectake:typea.int->at->at=funnl()->ifn=0thenNilelsematchl()withNil->Nil|Cons(x,l')->Cons(x,take(n-1)l')letfor_all:typea.(a->bool)->aSeq.t->bool=funfs->letrecauxs=matchs()withSeq.Nil->true|Seq.Cons(v,s)->fv&&auxsinauxs(* For compatibility with versions older than ocaml.4.11.0 *)letrecappendseq1seq2()=matchseq1()with|Nil->seq2()|Cons(x,next)->Cons(x,appendnextseq2)(* Since 4.14 *)letrecfor_all2fxsys=matchxs()with|Nil->true|Cons(x,xs)->(matchys()with|Nil->true|Cons(y,ys)->fxy&&for_all2fxsys)endletshufflestatearr=letrecauxn=ifn>1then(letk=Random.State.intstate(n+1)inlettemp=arr.(n)inarr.(n)<-arr.(k);arr.(k)<-temp;aux(n-1))inletlen=Array.lengtharrinaux(len-1);()