123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990# 1 "src/base/misc/owl_utils_multimap.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2019 Liang Wang <liang.wang@cl.cam.ac.uk>
*)(* An implementation of an ordered multimap for Owl's internal use.
* Simulates an ordered multimap using Map and Owl_utils.Stack values.
* Functions behave in the same way as those in Map, with the difference that
* one key can be bound to multiple values.
* Access and removals are O(log n). *)moduleMake(Ord:Map.OrderedType)=structmoduleStack=Owl_utils.StackmoduleMap=Map.Make(Ord)typekey=Ord.ttype'at=('aStack.t)Map.tlet_failf_name=failwith("owl_utils_multimap: "^f_name^": no stack should be empty")letempty=Map.emptyletis_empty=Map.is_emptyletmem=Map.memletaddkvmap=ifMap.memkmapthen(letstack_k=Map.findkmapinStack.pushstack_kv;map)else(letstack_k=Stack.make()inStack.pushstack_kv;Map.addkstack_kmap)letremovekmap=letstack_k=matchMap.find_optkmapwith|Somes->s|None->raiseNot_foundinlet()=matchStack.popstack_kwith|Some_->()|None->_fail"remove"inifStack.is_emptystack_kthenMap.removekmapelsemapletfindkmap=letstack_k=matchMap.find_optkmapwith|Somes->s|None->raiseNot_foundinmatchStack.peekstack_kwith|Somev->v|None->_fail"find"letmax_bindingmap=letk,stack=matchMap.max_binding_optmapwith|Some(k,s)->k,s|None->raiseNot_foundinletv=matchStack.peekstackwith|Somev->v|None->_fail"max_binding"ink,vletfind_first_optfmap=matchMap.find_first_optfmapwith|Some(k,s)->(matchStack.peekswith|Somev->Some(k,v)|None->_fail"find_first_opt")|None->Noneend