diff --git a/src/irmin-pack/atomic_write.ml b/src/irmin-pack/atomic_write.ml index 7ee92ec4f6..0caddbaf88 100644 --- a/src/irmin-pack/atomic_write.ml +++ b/src/irmin-pack/atomic_write.ml @@ -30,65 +30,8 @@ module Value = struct end end -(* FIXME: remove code duplication with irmin/atomic_write *) module Closeable (AW : S) = struct - type t = { closed : bool ref; t : AW.t } - type key = AW.key - type value = AW.value + include Irmin.Atomic_write.Check_closed_store (AW) - let check_not_closed t = if !(t.closed) then raise Irmin.Closed - - let mem t k = - check_not_closed t; - AW.mem t.t k - - let find t k = - check_not_closed t; - AW.find t.t k - - let set t k v = - check_not_closed t; - AW.set t.t k v - - let test_and_set t k ~test ~set = - check_not_closed t; - AW.test_and_set t.t k ~test ~set - - let remove t k = - check_not_closed t; - AW.remove t.t k - - let list t = - check_not_closed t; - AW.list t.t - - type watch = AW.watch - - let watch t ?init f = - check_not_closed t; - AW.watch t.t ?init f - - let watch_key t k ?init f = - check_not_closed t; - AW.watch_key t.t k ?init f - - let unwatch t w = - check_not_closed t; - AW.unwatch t.t w - - let make_closeable t = { closed = ref false; t } - - let close t = - if !(t.closed) then Lwt.return_unit - else ( - t.closed := true; - AW.close t.t) - - let clear t = - check_not_closed t; - AW.clear t.t - - let flush t = - check_not_closed t; - AW.flush t.t + let flush t = get_if_open_exn t |> AW.flush end diff --git a/src/irmin-pack/indexable.ml b/src/irmin-pack/indexable.ml index e16ee6d0c8..d66ccc561f 100644 --- a/src/irmin-pack/indexable.ml +++ b/src/irmin-pack/indexable.ml @@ -17,66 +17,22 @@ include Indexable_intf open! Import -(* FIXME: remove code duplication with irmin/indexable *) -module Closeable (S : S) = struct - type 'a t = { closed : bool ref; t : 'a S.t } - type key = S.key - type hash = S.hash - type value = S.value +module Closeable (CA : S) = struct + include Irmin.Indexable.Check_closed_store (CA) - module Key = S.Key + (** override of {!Irmin.Indexable.S.add} to allow read-only *) + let add t v = (get_if_open_exn t |> CA.add) v - let check_not_closed t = if !(t.closed) then raise Irmin.Closed + (** override of {!Irmin.Indexable.S.unsafe_add} to allow read-only *) + let unsafe_add t k v = (get_if_open_exn t |> CA.unsafe_add) k v - let mem t k = - check_not_closed t; - S.mem t.t k - - let find t k = - check_not_closed t; - S.find t.t k - - let index t h = - check_not_closed t; - S.index t.t h - - let index_direct t h = - check_not_closed t; - S.index_direct t.t h - - let add t v = - check_not_closed t; - S.add t.t v - - let unsafe_add t k v = - check_not_closed t; - S.unsafe_add t.t k v - - let batch t f = - check_not_closed t; - S.batch t.t (fun w -> f { t = w; closed = t.closed }) - - let close t = - if !(t.closed) then Lwt.return_unit - else ( - t.closed := true; - S.close t.t) + let index_direct t h = (get_if_open_exn t |> CA.index_direct) h let unsafe_append ~ensure_unique ~overcommit t k v = - check_not_closed t; - S.unsafe_append ~ensure_unique ~overcommit t.t k v + (get_if_open_exn t |> CA.unsafe_append ~ensure_unique ~overcommit) k v - let unsafe_mem t k = - check_not_closed t; - S.unsafe_mem t.t k + let unsafe_mem t k = (get_if_open_exn t |> CA.unsafe_mem) k let unsafe_find ~check_integrity t k = - check_not_closed t; - S.unsafe_find ~check_integrity t.t k - - let make_closeable t = { closed = ref false; t } - - let get_open_exn t = - check_not_closed t; - t.t + (get_if_open_exn t |> CA.unsafe_find ~check_integrity) k end diff --git a/src/irmin-pack/indexable_intf.ml b/src/irmin-pack/indexable_intf.ml index 3867797d45..6a3211debf 100644 --- a/src/irmin-pack/indexable_intf.ml +++ b/src/irmin-pack/indexable_intf.ml @@ -51,6 +51,6 @@ module type Sigs = sig S with type key = CA.key and type hash = CA.hash and type value = CA.value val make_closeable : 'a CA.t -> 'a t - val get_open_exn : 'a t -> 'a CA.t + val get_if_open_exn : 'a t -> 'a CA.t end end diff --git a/src/irmin-pack/unix/pack_store.ml b/src/irmin-pack/unix/pack_store.ml index f2c153e39f..ea2aa10ff0 100644 --- a/src/irmin-pack/unix/pack_store.ml +++ b/src/irmin-pack/unix/pack_store.ml @@ -507,14 +507,17 @@ struct let v ~config ~fm ~dict ~dispatcher = Inner.v ~config ~fm ~dict ~dispatcher |> make_closeable - let cast t = Inner.cast (get_open_exn t) |> make_closeable + let cast t = Inner.cast (get_if_open_exn t) |> make_closeable let integrity_check ~offset ~length k t = - Inner.integrity_check ~offset ~length k (get_open_exn t) + Inner.integrity_check ~offset ~length k (get_if_open_exn t) module Entry_prefix = Inner.Entry_prefix let read_and_decode_entry_prefix = Inner.read_and_decode_entry_prefix - let index_direct_with_kind t = Inner.index_direct_with_kind (get_open_exn t) - let purge_lru t = Inner.purge_lru (get_open_exn t) + + let index_direct_with_kind t = + Inner.index_direct_with_kind (get_if_open_exn t) + + let purge_lru t = Inner.purge_lru (get_if_open_exn t) end diff --git a/src/irmin/atomic_write.ml b/src/irmin/atomic_write.ml index e111fa5a0f..7bf9b0db10 100644 --- a/src/irmin/atomic_write.ml +++ b/src/irmin/atomic_write.ml @@ -17,65 +17,45 @@ open Import include Atomic_write_intf -module Check_closed (Make_atomic_write : Maker) (K : Type.S) (V : Type.S) = -struct - module S = Make_atomic_write (K) (V) - - type t = { closed : bool ref; t : S.t } - type key = S.key - type value = S.value +module Check_closed_store (AW : S) = struct + type t = { closed : bool ref; t : AW.t } + type key = AW.key + type value = AW.value + type watch = AW.watch - let check_not_closed t = if !(t.closed) then raise Store_properties.Closed + let make_closeable t = { closed = ref false; t } - let mem t k = - check_not_closed t; - S.mem t.t k + let get_if_open_exn t = + if !(t.closed) then raise Store_properties.Closed else t.t - let find t k = - check_not_closed t; - S.find t.t k - - let set t k v = - check_not_closed t; - S.set t.t k v + let mem t k = (get_if_open_exn t |> AW.mem) k + let find t k = (get_if_open_exn t |> AW.find) k + let set t k v = (get_if_open_exn t |> AW.set) k v let test_and_set t k ~test ~set = - check_not_closed t; - S.test_and_set t.t k ~test ~set - - let remove t k = - check_not_closed t; - S.remove t.t k + (get_if_open_exn t |> AW.test_and_set) k ~test ~set - let list t = - check_not_closed t; - S.list t.t - - type watch = S.watch - - let watch t ?init f = - check_not_closed t; - S.watch t.t ?init f - - let watch_key t k ?init f = - check_not_closed t; - S.watch_key t.t k ?init f - - let unwatch t w = - check_not_closed t; - S.unwatch t.t w - - let v conf = - let+ t = S.v conf in - { closed = ref false; t } + let remove t k = (get_if_open_exn t |> AW.remove) k + let list t = get_if_open_exn t |> AW.list + let watch t ?init f = (get_if_open_exn t |> AW.watch) ?init f + let watch_key t k ?init f = (get_if_open_exn t |> AW.watch_key) k ?init f + let unwatch t w = (get_if_open_exn t |> AW.unwatch) w let close t = if !(t.closed) then Lwt.return_unit else ( t.closed := true; - S.close t.t) + AW.close t.t) - let clear t = - check_not_closed t; - S.clear t.t + let clear t = get_if_open_exn t |> AW.clear +end + +module Check_closed (Make_atomic_write : Maker) (K : Type.S) (V : Type.S) = +struct + module AW = Make_atomic_write (K) (V) + include Check_closed_store (AW) + + let v conf = + let+ t = AW.v conf in + { closed = ref false; t } end diff --git a/src/irmin/atomic_write_intf.ml b/src/irmin/atomic_write_intf.ml index 77299105f6..15f506c225 100644 --- a/src/irmin/atomic_write_intf.ml +++ b/src/irmin/atomic_write_intf.ml @@ -90,5 +90,21 @@ module type Sigs = sig module type S = S module type Maker = Maker + module Check_closed_store (AW : S) : sig + include + S + with type key = AW.key + and type value = AW.value + and type watch = AW.watch + + val make_closeable : AW.t -> t + (** [make_closeable t] returns a version of [t] that raises {!Irmin.Closed} + if an operation is performed when it is already closed. *) + + val get_if_open_exn : t -> AW.t + (** [get_if_open_exn t] returns the store (without close checks) if it is + open; otherwise raises {!Irmin.Closed} *) + end + module Check_closed (M : Maker) : Maker end diff --git a/src/irmin/indexable.ml b/src/irmin/indexable.ml index 6b5bd7d348..5f833bea85 100644 --- a/src/irmin/indexable.ml +++ b/src/irmin/indexable.ml @@ -44,48 +44,40 @@ struct let unsafe_add t h v = unsafe_add t h v >|= fun () -> h end -module Check_closed (CA : Maker) (Hash : Hash.S) (Value : Type.S) = struct - module S = CA (Hash) (Value) - module Key = S.Key +module Check_closed_store (CA : S) = struct + module Key = CA.Key - type 'a t = { closed : bool ref; t : 'a S.t } - type value = S.value - type key = S.key - type hash = S.hash + type 'a t = { closed : bool ref; t : 'a CA.t } + type value = CA.value + type key = CA.key + type hash = CA.hash - let check_not_closed t = if !(t.closed) then raise Store_properties.Closed + let make_closeable t = { closed = ref false; t } - let mem t k = - check_not_closed t; - S.mem t.t k + let get_if_open_exn t = + if !(t.closed) then raise Store_properties.Closed else t.t - let index t h = - check_not_closed t; - S.index t.t h - - let find t k = - check_not_closed t; - S.find t.t k - - let add t v = - check_not_closed t; - S.add t.t v - - let unsafe_add t k v = - check_not_closed t; - S.unsafe_add t.t k v + let mem t k = (get_if_open_exn t |> CA.mem) k + let index t h = (get_if_open_exn t |> CA.index) h + let find t k = (get_if_open_exn t |> CA.find) k + let add t v = (get_if_open_exn t |> CA.add) v + let unsafe_add t k v = (get_if_open_exn t |> CA.unsafe_add) k v let batch t f = - check_not_closed t; - S.batch t.t (fun w -> f { t = w; closed = t.closed }) - - let v conf = - let+ t = S.v conf in - { closed = ref false; t } + (get_if_open_exn t |> CA.batch) (fun w -> f { t = w; closed = t.closed }) let close t = if !(t.closed) then Lwt.return_unit else ( t.closed := true; - S.close t.t) + CA.close t.t) +end + +module Check_closed (M : Maker) (Hash : Hash.S) (Value : Type.S) = struct + module CA = M (Hash) (Value) + include Check_closed_store (CA) + + let v conf = + let+ t = CA.v conf in + { closed = ref false; t } end diff --git a/src/irmin/indexable_intf.ml b/src/irmin/indexable_intf.ml index e97e610951..e7c084e8a2 100644 --- a/src/irmin/indexable_intf.ml +++ b/src/irmin/indexable_intf.ml @@ -132,5 +132,18 @@ module type Sigs = sig and type hash = Key.t and type value = S.value + module Check_closed_store (CA : S) : sig + include + S with type key = CA.key and type hash = CA.hash and type value = CA.value + + val make_closeable : 'a CA.t -> 'a t + (** [make_closeable t] returns a version of [t] that raises {!Irmin.Closed} + if an operation is performed when it is already closed. *) + + val get_if_open_exn : 'a t -> 'a CA.t + (** [get_if_open_exn t] returns the store (without close checks) if it is + open; otherwise raises {!Irmin.Closed} *) + end + module Check_closed (M : Maker) : Maker end