Ezirmin has now been merged into Irmin (See https://github.com/mirage/irmin/pull/1014).
Ezirmin is an easy interface on top of the Irmin library. It comes with set of mergeable datatypes, instantiated to specific backends to quickly get going. For example,
$ utop
utop # #require "ezirmin";;
utop # module M = Ezirmin.FS_queue(Tc.String);; (* Mergeable queue of strings *)
utop # open M;;
utop # open Lwt.Infix;;
utop # let m = Lwt_main.run (init ~root:"/tmp/ezirminq" ~bare:true () >>= master);;
val m : branch = <abstr>
utop # push m ["home"; "todo"] "buy milk";;
- : unit = ()
utop # push m ["work"; "todo"] "publish ezirmin";;
- : unit = ()
This mergeable queue is saved in the git repository at /tmp/ezirminq. In
another terminal,
$ utop
utop # #require "ezirmin";;
utop # module M = Ezirmin.FS_queue(Tc.String);; (* Mergeable queue of strings *)
utop # open M;;
utop # open Lwt.Infix;;
utop # let m = Lwt_main.run (init ~root:"/tmp/ezirminq" ~bare:true () >>= master);;
val m : branch = <abstr>
utop # pop m ["home"; "todo"];;
- : string option = Some "buy milk"
For concurrency control, use branches. In the first terminal,
utop # let wip_t1 = Lwt_main.run @@ clone_force m "wip_t1";;
utop # push wip_t1 ["home"; "todo"] "walk dog";;
- : unit = ()
utop # push wip_t1 ["home"; "todo"] "take out trash";;
- : unit = ()
The changes are not visible until the branches are merged.
utop # to_list m ["home"; "todo"];;
- : string list = []
utop # merge wip_t1 ~into:m;;
- : unit = ()
utop # to_list m ["home"; "todo"];;
- : string list = ["walk dog"; "take out trash"]
In addition to the data structures being mergeable, they are also persistent. In particular, every object stored in Irmin has complete provenance. Ezimrin simplifies working with object history.
let run = Lwt_main.run
let repo = run @@ init ()
let path = ["Books"; "Ovine Supply Logistics"]
let push_msg = push m ~path;;
run begin
push_msg "Baa" >>= fun () ->
push_msg "Baa" >>= fun () ->
push_msg "Black" >>= fun () ->
push_msg "Camel"
end;;
run @@ to_list m path;;
- : string list = ["Baa"; "Baa"; "Black"; "Camel"]
Clearly this is wrong. Let's fix this by reverting to earlier version:
let m_1::_ = run @@ predecessors repo m;; (** HEAD~1 version *)
run @@ to_list m_1 path;;
- : string list = ["Baa"; "Baa"; "Black"]
run @@ update_branch m ~set:m_1;;
run @@ to_list m path;;
- : string list = ["Baa"; "Baa"; "Black"]
Now that we've undone the error, we can do the right thing.
run @@ push_msg "Sheep";;
run @@ to_list m path;;
- : string list = ["Baa"; "Baa"; "Black"; "Sheep"]
The mergeable datatypes currently available are:
O(n) operation where n is the size
of the log.O(1)
operationO(1) push and pop operations.Since these datatypes are defined such that a merge is always possible and that merges in different orders converge, they are CRDTs.
The backends available are:
Ezirmin is distributed under the ISC license.
Homepage: https://github.com/kayceesrk/ezirmin
Contact: KC Sivaramakrishnan <sk826@cl.cam.ac.uk>
Ezirmin can be installed with opam:
opam install ezirmin
If you don't use opam consult the opam file for build instructions.
The documentation and API reference is automatically generated by ocamldoc
from the interfaces. It can be consulted online and there is a generated
version in the doc directory of the distribution.
If you installed Ezirmin with opam sample programs are located in the
directory opam config var ezirmin:doc.
In the distribution sample programs and tests are located in the
examples directory of the distribution. They can be built and run
with:
topkg build --tests true && topkg test
OCaml
99.6%
Ezirmin has now been merged into Irmin (See https://github.com/mirage/irmin/pull/1014).
Ezirmin is an easy interface on top of the Irmin library. It comes with set of mergeable datatypes, instantiated to specific backends to quickly get going. For example,
$ utop
utop # #require "ezirmin";;
utop # module M = Ezirmin.FS_queue(Tc.String);; (* Mergeable queue of strings *)
utop # open M;;
utop # open Lwt.Infix;;
utop # let m = Lwt_main.run (init ~root:"/tmp/ezirminq" ~bare:true () >>= master);;
val m : branch = <abstr>
utop # push m ["home"; "todo"] "buy milk";;
- : unit = ()
utop # push m ["work"; "todo"] "publish ezirmin";;
- : unit = ()
This mergeable queue is saved in the git repository at /tmp/ezirminq. In
another terminal,
$ utop
utop # #require "ezirmin";;
utop # module M = Ezirmin.FS_queue(Tc.String);; (* Mergeable queue of strings *)
utop # open M;;
utop # open Lwt.Infix;;
utop # let m = Lwt_main.run (init ~root:"/tmp/ezirminq" ~bare:true () >>= master);;
val m : branch = <abstr>
utop # pop m ["home"; "todo"];;
- : string option = Some "buy milk"
For concurrency control, use branches. In the first terminal,
utop # let wip_t1 = Lwt_main.run @@ clone_force m "wip_t1";;
utop # push wip_t1 ["home"; "todo"] "walk dog";;
- : unit = ()
utop # push wip_t1 ["home"; "todo"] "take out trash";;
- : unit = ()
The changes are not visible until the branches are merged.
utop # to_list m ["home"; "todo"];;
- : string list = []
utop # merge wip_t1 ~into:m;;
- : unit = ()
utop # to_list m ["home"; "todo"];;
- : string list = ["walk dog"; "take out trash"]
In addition to the data structures being mergeable, they are also persistent. In particular, every object stored in Irmin has complete provenance. Ezimrin simplifies working with object history.
let run = Lwt_main.run
let repo = run @@ init ()
let path = ["Books"; "Ovine Supply Logistics"]
let push_msg = push m ~path;;
run begin
push_msg "Baa" >>= fun () ->
push_msg "Baa" >>= fun () ->
push_msg "Black" >>= fun () ->
push_msg "Camel"
end;;
run @@ to_list m path;;
- : string list = ["Baa"; "Baa"; "Black"; "Camel"]
Clearly this is wrong. Let's fix this by reverting to earlier version:
let m_1::_ = run @@ predecessors repo m;; (** HEAD~1 version *)
run @@ to_list m_1 path;;
- : string list = ["Baa"; "Baa"; "Black"]
run @@ update_branch m ~set:m_1;;
run @@ to_list m path;;
- : string list = ["Baa"; "Baa"; "Black"]
Now that we've undone the error, we can do the right thing.
run @@ push_msg "Sheep";;
run @@ to_list m path;;
- : string list = ["Baa"; "Baa"; "Black"; "Sheep"]
The mergeable datatypes currently available are:
O(n) operation where n is the size
of the log.O(1)
operationO(1) push and pop operations.Since these datatypes are defined such that a merge is always possible and that merges in different orders converge, they are CRDTs.
The backends available are:
Ezirmin is distributed under the ISC license.
Homepage: https://github.com/kayceesrk/ezirmin
Contact: KC Sivaramakrishnan <sk826@cl.cam.ac.uk>
Ezirmin can be installed with opam:
opam install ezirmin
If you don't use opam consult the opam file for build instructions.
The documentation and API reference is automatically generated by ocamldoc
from the interfaces. It can be consulted online and there is a generated
version in the doc directory of the distribution.
If you installed Ezirmin with opam sample programs are located in the
directory opam config var ezirmin:doc.
In the distribution sample programs and tests are located in the
examples directory of the distribution. They can be built and run
with:
topkg build --tests true && topkg test
OCaml
99.6%