Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file hashtbl.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2020 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)lethash=Stdlib.Hashtbl.hashletseeded_hash=Stdlib.Hashtbl.seeded_hashlethash_param~meaningful~totalv=Stdlib.Hashtbl.hash_parammeaningfultotalvletseeded_hash_param~meaningful~totalseedv=Stdlib.Hashtbl.seeded_hash_parammeaningfultotalseedvmoduletypeS=Bare_functor_outputs.Hashtbl.SmoduleMake(H:Stdlib.Hashtbl.HashedType):Swithtypekey=H.t=structopenSeqmoduleLegacy=Stdlib.Hashtbl.Make(H)includeLegacyletiter_eft=iter_e(fun(k,v)->fkv)(to_seqt)letiter_sft=iter_s(fun(k,v)->fkv)(to_seqt)letiter_esft=iter_es(fun(k,v)->fkv)(to_seqt)letiter_pft=iter_p(fun(k,v)->fkv)(to_seqt)letiter_epft=iter_ep(fun(k,v)->fkv)(to_seqt)letfold_eftinit=fold_left_e(funacc(k,v)->fkvacc)init(to_seqt)letfold_sftinit=fold_left_s(funacc(k,v)->fkvacc)init(to_seqt)letfold_esftinit=fold_left_es(funacc(k,v)->fkvacc)init(to_seqt)letfind=find_optlettry_map_inplaceft=filter_map_inplace(funkv->matchfkvwithError_->None|Okr->Somer)tendmoduletypeSeededS=Bare_functor_outputs.Hashtbl.SeededSmoduleMakeSeeded(H:Stdlib.Hashtbl.SeededHashedType):SeededSwithtypekey=H.t=structopenSeqmoduleLegacy=Stdlib.Hashtbl.MakeSeeded(H)includeLegacyletiter_eft=iter_e(fun(k,v)->fkv)(to_seqt)letiter_sft=iter_s(fun(k,v)->fkv)(to_seqt)letiter_esft=iter_es(fun(k,v)->fkv)(to_seqt)letiter_epft=iter_ep(fun(k,v)->fkv)(to_seqt)letiter_pft=iter_p(fun(k,v)->fkv)(to_seqt)letfold_eftinit=fold_left_e(funacc(k,v)->fkvacc)init(to_seqt)letfold_sftinit=fold_left_s(funacc(k,v)->fkvacc)init(to_seqt)letfold_esftinit=fold_left_es(funacc(k,v)->fkvacc)init(to_seqt)letfind=find_optlettry_map_inplaceft=filter_map_inplace(funkv->matchfkvwithError_->None|Okr->Somer)tendmoduletypeS_ES=Bare_functor_outputs.Hashtbl.S_ESmoduleMake_es(H:Stdlib.Hashtbl.HashedType):S_ESwithtypekey=H.t=struct(* This [_es] overlay on top of Hashtables prevents programmers from shooting
themselves in the feet with some common errors. Specifically, it prevents
race-conditions whereby the same key is bound again before the promise it
is already bound to resolves.
More details in the interface: {!Bare_functor_outputs.Hashtbl.S_ES}
To achieve this, the library maintains the following invariant:
- at any point in time, keys are associated to at most one promise *)openSeqopenMonadmoduleT=Stdlib.Hashtbl.Make(H)typekey=H.ttype('a,'trace)t=('a,'trace)resultLwt.tT.tletcreaten=T.createnletcleart=T.iter(fun_a->Lwt.cancela)t;T.cleartletresett=T.iter(fun_a->Lwt.cancela)t;T.resettletfind_or_maketkmake=matchT.find_opttkwith|Somea->a|None->letp=Lwt.applymake()in(matchLwt.statepwith|Return(Ok_)->T.addtkp|Return(Error_)->()|Fail_->()|Sleep->T.addtkp;Lwt.on_anyp(functionOk_->()|Error_->T.removetk)(fun_->T.removetk));pletfindtk=T.find_opttkletremovetk=(matchT.find_opttkwithNone->()|Somea->Lwt.cancela);(* NOTE: we still need to call [T.remove] in case the promise is not
cancelable (in which case it is not rejected and thus not removed) *)T.removetkletmemtk=T.memtkletiter_with_waiting_esft=iter_es(fun(k,p)->Lwt.try_bind(fun()->p)(functionError_->unit_es|Okv->fkv)(fun_->unit_es))(T.to_seqt)letfold_with_waiting_esftinit=fold_left_es(funacc(k,p)->Lwt.try_bind(fun()->p)(functionError_->returnacc|Okv->fkvacc)(fun_->returnacc))init(T.to_seqt)letfold_keysftinit=T.fold(funk_acc->fkacc)tinitletfold_promisesftinit=T.foldftinitletfold_resolvedftinit=T.fold(funkpacc->matchLwt.statepwith|Lwt.Return(Okv)->fkvacc|Lwt.Return(Error_)|Lwt.Fail_|Lwt.Sleep->acc)tinitletiter_with_waiting_epft=Monad.join_ep@@fold_promises(funkpacc->letpromise=Lwt.try_bind(fun()->p)(functionError_->Monad.unit_es|Okv->fkv)(fun_->Monad.unit_es)inpromise::acc)t[]letlengtht=T.lengthtletstatst=T.statstend