123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149(*
* Copyright (c) 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.
*)open!ImportopenStore_propertiesmoduletypeS_without_key_impl=sigincludeRead_only.S(** @inline *)typehash(** The type of hashes of [value]. *)valadd:[>write]t->value->keyLwt.t(** Write the contents of a value to the store, and obtain its key. *)valunsafe_add:[>write]t->hash->value->keyLwt.t(** Same as {!add} but allows specifying the value's hash directly. The
backend might choose to discard that hash and/or can be corrupt if the
hash is not consistent. *)valindex:[>read]t->hash->keyoptionLwt.t(** Indexing maps the hash of a value to a corresponding key of that value in
the store. For stores that are addressed by hashes directly, this is
typically [fun _t h -> Lwt.return (Key.of_hash h)]; for stores with more
complex addressing schemes, [index] may attempt a lookup operation in the
store.
In general, indexing is best-effort and reveals no information about the
membership of the value in the store. In particular:
- [index t hash = Some key] doesn't guarantee [mem t key]: the value with
hash [hash] may still be absent from the store;
- [index t hash = None] doesn't guarantee that there is no [key] such that
[mem t key] and [Key.to_hash key = hash]: the value may still be present
in the store under a key that is not indexed. *)includeBatchwithtype'at:='at(** @inline *)endmoduletypeS=sig(** An {i indexable} store is a read-write store in which values can be added
and later found via their keys.
Keys are not necessarily portable between different stores, so each store
provides an {!val-index} mechanism to find keys by the hashes of the
values they reference. *)includeS_without_key_impl(* @inline *)moduleKey:Key.Swithtypet=keyandtypehash=hashendmoduletypeMaker=functor(Hash:Hash.S)(Value:Type.S)->sigincludeSwithtypevalue=Value.tandtypehash=Hash.tincludeOf_configwithtype'at:='at(** @inline *)end(** A {!Maker_concrete_key} is an indexable store in which the key type is
uniquely determined by the hash type and is stated up-front. *)moduletypeMaker_concrete_key1=sigtype'hkeymoduleKey:functor(Hash:Hash.S)->Key.Swithtypet=Hash.tkeyandtypehash=Hash.tmoduleMake:functor(Hash:Hash.S)(Value:Type.S)->sigincludeSwithtypevalue=Value.tandtypehash=Hash.tandtypekey=Hash.tkeyincludeOf_configwithtype'at:='at(** @inline *)endend(** Like {!Maker_concrete_key1}, but the key type may also depend on type of the
value that it references. *)moduletypeMaker_concrete_key2=sigtype('h,'v)keymoduleKey:functor(Hash:Hash.S)(Value:Type.S)->Key.Swithtypet=(Hash.t,Value.t)keyandtypehash=Hash.tmoduleMake:functor(Hash:Hash.S)(Value:Type.S)->sigincludeSwithtypevalue=Value.tandtypehash=Hash.tandtypekey=(Hash.t,Value.t)keyincludeOf_configwithtype'at:='at(** @inline *)endendmoduletypeSigs=sigmoduletypeS=SmoduletypeS_without_key_impl=S_without_key_implmoduletypeMaker=MakermoduletypeMaker_concrete_key1=Maker_concrete_key1moduletypeMaker_concrete_key2=Maker_concrete_key2moduleMaker_concrete_key2_of_1(X:Maker_concrete_key1):Maker_concrete_key2withtype('h,_)key='hX.keymoduleOf_content_addressable(Key:Type.S)(S:Content_addressable.Swithtypekey=Key.t):Swithtype'at='aS.tandtypekey=Key.tandtypehash=Key.tandtypevalue=S.valuemoduleCheck_closed_store(CA:S):sigincludeSwithtypekey=CA.keyandtypehash=CA.hashandtypevalue=CA.valuevalmake_closeable:'aCA.t->'at(** [make_closeable t] returns a version of [t] that raises {!Irmin.Closed}
if an operation is performed when it is already closed. *)valget_if_open_exn:'at->'aCA.t(** [get_if_open_exn t] returns the store (without close checks) if it is
open; otherwise raises {!Irmin.Closed} *)endmoduleCheck_closed(M:Maker):Makerend