123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081(*
* Copyright (c) 2020 KC Sivaramakrishnan <kc@kcsrk.info>
* Copyright (c) 2020 Anirudh Sunder Raj <anirudh6626@gmail.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!ImportmoduleBlob_log(T:Time.S)(V:Irmin.Type.S):Irmin.Contents.Swithtypet=(V.t*T.t)list=structtypet=(V.t*T.t)list[@@derivingirmin]letcompare_t=Irmin.Type.(unstage(compareT.t))letcompare(_,t1)(_,t2)=compare_tt1t2letnewer_thantimestampentries=letrecutilacc=function|[]->List.revacc|(_,x)::_whencompare_txtimestamp<=0->List.revacc|h::t->util(h::acc)tinutil[]entriesletmerge~oldv1v2=letopenIrmin.Merge.Infixinletok=Irmin.Merge.okinold()>>=*funold->letold=matcholdwithNone->[]|Someo->oinletl1,l2=matcholdwith|[]->(v1,v2)|(_,t)::_->(newer_thantv1,newer_thantv2)inletl3=List.sortcompare(List.rev_appendl1l2)inok(List.rev_appendl3old)letmerge=Irmin.Merge.(option(vtmerge))endmoduletypeS=sigmoduleStore:Irmin.KVtypevaluevalappend:path:Store.path->Store.t->value->unitLwt.tvalread_all:path:Store.path->Store.t->valuelistLwt.tendmoduleMake(Backend:Irmin.KV_maker)(T:Time.S)(V:Irmin.Type.S)=structmoduleStore=Backend.Make(Blob_log(T)(V))letempty_info=Store.Info.nonetypevalue=V.tletcreate_entryv=(v,T.now())letappend~pathtv=Store.findtpath>>=function|None->Store.set_exn~info:empty_infotpath[create_entryv]|Somel->Store.set_exn~info:empty_infotpath(create_entryv::l)letread_all~patht=Store.findtpath>|=function|None->[]|Somel->List.map(fun(v,_)->v)lendmoduleFS(V:Irmin.Type.S)=Make(Irmin_fs_unix.KV)(Time.Machine)(V)moduleMem(V:Irmin.Type.S)=Make(Irmin_mem.KV)(Time.Machine)(V)