123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146(*
* Copyright (c) 2021 Tarides <contact@tarides.com>
* Copyright (c) 2021 Gabriel Belouze <gabriel.belouze@ens.psl.eu>
*
* 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.
*)moduletypeS=sigtypet(** The type for vertices. For leafs its a map (key * value). For nodes it maps a [key] interval
to an [address]. *)typekeytypevaluetypeaddresstypestorevalcreate:store->Field.kind->address->t(** [create s k p] creates a new empty vertex (of kind either Leaf or Node), stored at address [p]
in [s]. *)valload:store->address->t(** [load s p] loads the table stored at address [p] in [s]. *)valreconstruct:t->Field.kind->(key*value)list->unit(** [reconstruct t kind kvs] overwrite [t] with the list of bindings [kvs] which is assumed to be
sorted. *)valmigrate:stringlist->Field.kind->string(** [migrate kvs kind] is the representation of the key-value association list [kvs] in a vertex
of type [kind] *)valleftmost:t->key(** [leftmost t] is the smallest key bound in [t] *)valsplit:t->address->key*t(** [split t p] moves half of the bindings from [t] (with keys larger than a pivot, which is the
middle key bounded in [t]) to a new table [t_mv] stored at address [p]. Return [pivot, t_mv]. *)valreplace:t->key->key->unit(** [replace t k1 k2] replaces key [k1] in [t] with [k2] *)valadd:t->key->value->unit(** [add t k v] adds a binding from [k] to [v] in [t]. Contrary to [Map.add], previous bindings
from [k] are not hidden, but deleted. *)valfind:t->key->value(** [find t k] returns the current binding of [k] in [t], or raises [Not_found] if no such binding
exists. *)typewith_neighbour={main:key*value;neighbour:(key*value)option;order:[`Lower|`Higher];}valfind_with_neighbour:t->key->with_neighbour(** [find_with_neighbour t k] as [find t k] but also returns a neighbour of [k] in [t] (the
right-most one when [k] has neighbours in both directions). *)valmem:t->key->bool(** [mem t k] checks if [k] is bound in [t] in case the vertex is a leaf and raises
[Invalid_argument] if its a node. *)valiter:t->(key->value->unit)->unit(** [iter t func] applies [func key value] on every bindings [(key, value)] stored in [t] *)valfold_left:('a->key*value->'a)->'a->t->'avalmerge:t->t->[`Partial|`Total]->unit(** [merge t1 t2 mode] merges bindings in [t1] and [t2]. A partial merge merely redistribute the
keys evenly among the nodes, a total merge moves all keys from [t2] to [t1]. It is assumed,
and relied upon, that all keys from [t2] are greater than every key from [t1]. *)valremove:t->key->unit(** [remove t k] removes the binding of [k] in [t], or raises [Not_found] if no such binding
exists. *)vallength:t->int(** [length t] is the number of keys bound in [t]. It takes constant time. *)valdepth:t->int(** [depth t] is the depth of the vertex [t]. *)valpp:tFmt.t(** [pp ppf t] outputs a human-readable representation of [t] to the formatter [ppf] *)endmoduletypeVALUE=sigtypetvalset:marker:(unit->unit)->bytes->off:int->t->unitvalget:bytes->off:int->tvalsize:intvalpp:tFmt.tvalkind:[`Leaf|`Node]endmoduletypeLEAFMAKER=functor(Params:Params.S)(Store:Store.S)(Key:Data.K)(Value:Data.V)->Swithtypekey:=Key.tandtypevalue:=Value.tandtypestore=Store.tandtypeaddress=Store.addressmoduletypeNODEMAKER=functor(Params:Params.S)(Store:Store.S)(Key:Data.K)->Swithtypekey:=Key.tandtypevalue:=Field.MakeCommon(Params).Address.tandtypestore=Store.tandtypeaddress=Store.addressmoduletypeMAKER=functor(Params:Params.S)(Store:Store.S)(Key:Data.K)(Value:VALUE)->Swithtypekey:=Key.tandtypevalue:=Value.tandtypestore=Store.tandtypeaddress=Store.addressmoduletypeVertex=sigmoduleLeafMake:LEAFMAKERmoduleNodeMake:NODEMAKERend