package irmin

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Merge provides functions to build custom 3-way merge operators for various user-defined contents.

Merge Results

type 'a result = [
  1. | `Ok of 'a
  2. | `Conflict of string
]

Type for merge results.

module Result : Tc.S1 with type 'a t = 'a result

Base functions on results.

val bind : 'a result Lwt.t -> ('a -> 'b result Lwt.t) -> 'b result Lwt.t

Monadic bind for results.

exception Conflict of string

Exception which might be raised when merging.

val exn : 'a result -> 'a Lwt.t

Convert `Conflict results to Conflict exceptions.

Merge Combinators

type 'a promise = unit -> 'a option result Lwt.t

An 'a promise is a function which, when called, will eventually return a value type of 'a. A promise is an optional, lazy and non-blocking value.

val promise : 'a -> 'a promise

promise a is the promise containing a.

val promise_map : ('a -> 'b) -> 'a promise -> 'b promise

promise_map f a is the promise containing f applied to what is promised by a.

val promise_bind : 'a promise -> ('a -> 'b promise) -> 'b promise

promise_bind a f is the promise returned by f applied to what is promised by a.

type 'a t = old:'a promise -> 'a -> 'a -> 'a result Lwt.t

Signature of a merge function. old is the value of the least-common ancestor.

              /----> t1 ----\
      ----> old              |--> result
              \----> t2 ----/
val seq : 'a t list -> 'a t

Call the merge functions in sequence. Stop as soon as one is not returning a conflict.

val apply : ('a -> 'b t) -> 'a -> 'b t

The apply combinator is useful to untie recursive loops when building a complex merge function.

val biject : 'a Tc.t -> 'b t -> ('a -> 'b) -> ('b -> 'a) -> 'a t

Use the merge function defined in another domain. If the converting functions raise any exception the merge is a conflict.

val biject' : 'a Tc.t -> 'b t -> ('a -> 'b Lwt.t) -> ('b -> 'a Lwt.t) -> 'a t

Same as biject but with blocking domain converting functions.

Basic Merges

val default : 'a Tc.t -> 'a t

Create a default merge function. This is a simple merge function which supports changes in one branch at a time:

  • if t1=t2 then the result of the merge is `OK t1;
  • if t1=old then the result of the merge is `OK t2;
  • if t2=old then return `OK t1;
  • otherwise the result is `Conflict.
val string : string t

The default string merge function. Do not do anything clever, just compare the strings using the default merge function.

val option : 'a Tc.t -> 'a t -> 'a option t

Lift a merge function to optional values of the same type. If all the provided values are inhabited, then call the provided merge function, otherwise use the same behavior as default.

val pair : 'a Tc.t -> 'b Tc.t -> 'a t -> 'b t -> ('a * 'b) t

Lift merge functions to pair of elements.

val triple : 'a Tc.t -> 'b Tc.t -> 'c Tc.t -> 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t

Lift merge functions to triple of elements.

val set : (module Set.S with type t = 'a) -> 'a t

List merge functions to sets.

Counters and Multisets

type counter = int

The type for counter values. It is expected that the only valid operations on counters are increment and decrement. The following merge functions ensure that the counter semantics are preserved: i.e. it ensures that the number of increments and decrements is preserved.

val counter : int t

The merge function for mergeable counters.

module MSet (M : Map.S) : sig ... end

Multi-sets.

Maps and Association Lists

We consider the only valid operations for maps and association lists to be:

  • Adding a new bindings to the map.
  • Removing a binding from the map.
  • Replacing an existing binding with a different value.
  • Trying to add an already existing binding is a no-op.

We thus assume that no operation on maps is modifying the key names. So the following merge functions ensures that (i) new bindings are preserved (ii) removed bindings stay removed and (iii) modified bindings are merged using the merge function of values.

Note: We only consider sets of bindings, instead of multisets. Application developers should take care of concurrent addition and removal of similar bindings themselves, by using the appropriate multi-sets.

val alist : 'a Tc.t -> 'b Tc.t -> ('a -> 'b option t) -> ('a * 'b) list t

Lift the merge functions to association lists.

module Map (M : Map.S) (X : Tc.S0 with type t = M.key) : sig ... end

Lift the merge functions to maps.

module OP : sig ... end

Useful merge operators.

OCaml

Innovation. Community. Security.