Library

Module

Module type

Parameter

Class

Class type

## Parameters

`module Pclock : Mirage_clock.PCLOCK`

## Signature

```
include Mirage_kv.RW
with type t = t
and type write_error =
[ `Msg of string
| `Hash_not_found of Digestif.SHA1.t
| `Reference_not_found of Git.Reference.t
| Mirage_kv.write_error ]
```

### Read-write Stores

There is a trade-off between durability and performance. If you want performance, use the `batch`

operation with a chain of sets and removes. They will be applied on the underlying storage layer all at once. Otherwise `set`

and `remove`

will cause a flush in the underlying storage layer every time, which could degrade performance.

`include Mirage_kv.RO with type t = t`

### Read-only key-value stores

The type for errors.

`type t = t`

The type representing the internal state of the key-value store.

Disconnect from the key-value store. While this might take some time to complete, it can never result in an error.

`type key = Mirage_kv.Key.t`

The type for keys.

`exists t k`

is `Some `Value`

if `k`

is bound to a value in `t`

, `Some `Dictionary`

if `k`

is a prefix of a valid key in `t`

and `None`

if no key with that prefix exists in `t`

.

`exists`

answers two questions: does the key exist and is it referring to a value or a dictionary.

An error occurs when the underlying storage layer fails.

`get t k`

is the value bound to `k`

in `t`

.

The result is `Error (`Value_expected k)`

if `k`

refers to a dictionary in `t`

.

`get_partial t k ~offset ~length`

is the `length`

bytes wide value bound at `offset`

of `k`

in `t`

.

If the size of `k`

is less than `offset`

, `get_partial`

returns an empty string. If the size of `k`

is less than `offset`

+`length`

, `get_partial`

returns a short string. The result is `Error (`Value_expected k)`

if `k`

refers to a dictionary in `t`

.

`list t k`

is the list of entries and their types in the dictionary referenced by `k`

in `t`

.

The result is `Error (`Dictionary_expected k)`

if `k`

refers to a value in `t`

.

`last_modified t k`

is the last time the value bound to `k`

in `t`

has been modified.

The modification time `(d, ps)`

is a span for the signed POSIX picosecond span `d`

* 86_400e12 + `ps`

. `d`

is a signed number of POSIX days and `ps`

a number of picoseconds in the range [`0`

;`86_399_999_999_999_999L`

].

When the value bound to `k`

is a dictionary, the modification time is the latest modification of all entries in that dictionary. This behaviour is only one level deep and not recursive.

`digest t k`

is the unique digest of the value bound to `k`

in `t`

.

When the value bound to `k`

is a dictionary, the digest is a unique and deterministic digest of its entries.

`type nonrec write_error = [ `

`|`

``Msg of string`

`|`

``Hash_not_found of Digestif.SHA1.t`

`|`

``Reference_not_found of Git.Reference.t`

`|`

`Mirage_kv.write_error`

` ]`

The type for write errors.

`val pp_write_error : write_error Fmt.t`

The pretty-printer for `pp_write_error`

.

`val set : t -> key -> string -> (unit, write_error) Stdlib.result Lwt.t`

`set t k v`

replaces the binding `k -> v`

in `t`

.

Durability is guaranteed unless `set`

is run inside an enclosing `batch`

operation, where durability will be guaranteed at the end of the batch.

```
val set_partial :
t ->
key ->
offset:int ->
string ->
(unit, write_error) Stdlib.result Lwt.t
```

`set_partial t k offset v`

attempts to write `v`

at `offset`

in the value bound to `k`

in `t`

. If `k`

contains directories that do not exist, `set_partial`

will attempt to create them. If the size of `k`

is less than `offset`

, `set_partial`

appends `v`

at the end of `k`

. If the size of `k`

is greater than `offset`

+length of `v`

, `set_partial`

leaves the last bytes of `k`

unchanged.

The result is `Error (`Value_expected k)`

if `k`

refers to a dictionary in `t`

.

`val remove : t -> key -> (unit, write_error) Stdlib.result Lwt.t`

`remove t k`

removes any binding of `k`

in `t`

. If `k`

was bound to a dictionary, the full dictionary will be removed.

Durability is guaranteed unless `remove`

is run inside an enclosing `batch`

operation, where durability will be guaranteed at the end of the batch.

```
val rename :
t ->
source:key ->
dest:key ->
(unit, write_error) Stdlib.result Lwt.t
```

`rename t source dest`

rename `source`

to `dest`

in `t`

. If `source`

and `dest`

are both bound to values in `t`

, `dest`

is removed and the binding of `source`

is moved to `dest`

. If `dest`

is bound to a dictionary in `t`

, `source`

is moved inside `dest`

. If `source`

is bound to a dictionary, the full dictionary is moved.

The result is `Error (`Not_found source)`

if `source`

does not exists in `t`

. The result is `Error (`Value_expected source)`

if `source`

is bound to a dictionary in `t`

and `dest`

is bound to a value in `t`

.

`batch t f`

run `f`

in batch. Ensure the durability of operations.

Since a batch is applied at once, the readings inside a batch will return the state before the entire batch. Concurrent operations will not affect other ones executed during the batch.

Batch applications can fail to apply if other operations are happening concurrently. In case of failure, `f`

will run again with the most recent version of `t`

. The result is `Error `Too_many_retries`

if `f`

is run for more then `retries`

attemps (default is `13`

).