12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788# 1 "src/base/misc/owl_utils_multimap.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2020 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.tMap.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