From f66d223c77187cf8efa7293605452f8b2449f9aa Mon Sep 17 00:00:00 2001 From: gwenaelle Date: Wed, 21 Sep 2022 10:39:36 +0200 Subject: [PATCH 1/5] irmin-pack: Add sequential accessors & clean dispatcher --- src/irmin-pack/unix/dispatcher.ml | 79 +++++++++++++++++++++++++- src/irmin-pack/unix/dispatcher_intf.ml | 34 ++++++++++- src/irmin-pack/unix/ext.ml | 2 +- src/irmin-pack/unix/gc.ml | 2 +- src/irmin-pack/unix/snapshot.ml | 5 +- test/irmin-pack/common.ml | 2 +- test/irmin-pack/test_inode.ml | 2 +- 7 files changed, 114 insertions(+), 12 deletions(-) diff --git a/src/irmin-pack/unix/dispatcher.ml b/src/irmin-pack/unix/dispatcher.ml index 7107cbd42e..83710093dd 100644 --- a/src/irmin-pack/unix/dispatcher.ml +++ b/src/irmin-pack/unix/dispatcher.ml @@ -28,7 +28,7 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : module Errs = Fm.Errs module Control = Fm.Control - type t = { fm : Fm.t; root : string } + type t = { fm : Fm.t } type location = Prefix | Suffix [@@deriving irmin] type accessor = { poff : int63; len : int; location : location } @@ -40,8 +40,8 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : [location] is a file identifier. *) - let v ~root fm = - let t = { fm; root } in + let v fm = + let t = { fm } in Ok t let get_prefix t = @@ -250,4 +250,77 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : let shrink_accessor_exn a ~new_len = if new_len > a.len then failwith "shrink_accessor_exn to larger accessor"; { a with len = new_len } + + module Sequential = struct + let create_accessor_exn prefix_len suffix_len ~off ~len = + let open Int63.Syntax in + if off >= prefix_len then + let off = off - prefix_len in + let entry_end_offset = off + Int63.of_int len in + if entry_end_offset > suffix_len then + raise (Errors.Pack_error `Read_out_of_bounds) + else { poff = off; len; location = Suffix } + else + let entry_end_offset = off + Int63.of_int len in + if entry_end_offset > prefix_len then + raise (Errors.Pack_error `Read_out_of_bounds) + else { poff = off; len; location = Prefix } + + let create_accessor_from_range_exn prefix_len suffix_len ~off ~min_len + ~max_len = + let open Int63.Syntax in + if off >= prefix_len then + let off = off - prefix_len in + let max_entry_len = suffix_len - off in + let len = + let min_len = Int63.of_int min_len in + let max_len = Int63.of_int max_len in + if suffix_len < min_len then + raise (Errors.Pack_error `Read_out_of_bounds) + else if max_entry_len > max_len then max_len + else max_entry_len + in + let len = Int63.to_int len in + { poff = off; len; location = Suffix } + else + let max_entry_len = prefix_len - off in + let len = + let min_len = Int63.of_int min_len in + let max_len = Int63.of_int max_len in + if prefix_len < min_len then + raise (Errors.Pack_error `Read_out_of_bounds) + else if max_entry_len > max_len then max_len + else max_entry_len + in + let len = Int63.to_int len in + { poff = off; len; location = Prefix } + + let create_accessor_seq t ~min_header_len ~max_header_len ~read_len = + let open Int63.Syntax in + let buf = Bytes.create max_header_len in + let prefix_len = + match Fm.prefix t.fm with + | Some prefix -> ( + match Io.read_size prefix with + | Ok len -> len + | Error _ -> Int63.zero) + | None -> Int63.zero + in + let suffix_len = Fm.Suffix.end_offset (Fm.suffix t.fm) in + let end_offset = prefix_len + suffix_len in + let f off = + if off < end_offset then ( + let accessor = + create_accessor_from_range_exn prefix_len suffix_len ~off + ~min_len:min_header_len ~max_len:max_header_len + in + read_exn t accessor buf; + let len = read_len buf in + Some + ( (off, create_accessor_exn prefix_len suffix_len ~off ~len), + Int63.(add off (of_int len)) )) + else None + in + Seq.unfold f Int63.zero + end end diff --git a/src/irmin-pack/unix/dispatcher_intf.ml b/src/irmin-pack/unix/dispatcher_intf.ml index da8ff9cd07..0835f5b8a4 100644 --- a/src/irmin-pack/unix/dispatcher_intf.ml +++ b/src/irmin-pack/unix/dispatcher_intf.ml @@ -31,7 +31,7 @@ module type S = sig finalisation, an accessor could no longer point to a valid area because the GC changes the domain of valid readable areas) *) - val v : root:string -> Fm.t -> (t, [> Fm.Errs.t ]) result + val v : Fm.t -> (t, [> Fm.Errs.t ]) result val create_accessor_exn : t -> off:int63 -> len:int -> accessor (** [create_accessor_exn] returns an accessor if [off] and [len] designate a @@ -50,6 +50,38 @@ module type S = sig (** [shrink_accessor_exn a ~new_len] is [a] where the length is smaller than in [a].*) + module Sequential : sig + val create_accessor_exn : int63 -> int63 -> off:int63 -> len:int -> accessor + (** [create_accessor_exn prefix_len suffix_len ~off ~len] returns an + accessor if [off] and [len] designate a readable area of the pack + files, otherwise it raises one of [Errors.Pack_error `Read_out_of_bounds]. + [prefix_len] and [suffix_len] are directly given to the function as they + are computed by costly functions to call. + In the contrary of the above create_accessor_exn function, it does not + take "virtual" lengths (aka. lengths taking gc'ed chunks into account), + but physical lengths in argument. *) + + val create_accessor_from_range_exn : + int63 -> int63 -> off:int63 -> min_len:int -> max_len:int -> accessor + (** [create_accessor_from_range_exn] is similar to + [create_accessor_exn] except that the precise length of the span will be + decided during the call. *) + + val create_accessor_seq : + t -> + min_header_len:int -> + max_header_len:int -> + read_len:(bytes -> int) -> + (int63 * accessor) Seq.t + (** [create_accessor_seq ~min_header_len ~max_header_len ~read_len] + returns a sequence of accessors, which simulates iterating sequentially + trough the entries of a pack file. [min_header_len] & [max_header_len] + represents the minimum & maximum lengths required to read the header of + an entry. [read_len] will then be called with a buffer containing the + header of the entry and should return the total length of the entry (the + length of he header plus the length of the payload)*) + end + val read_exn : t -> accessor -> bytes -> unit (** [read_exn] either reads in the prefix or the suffix file, depending on [accessor]. *) diff --git a/src/irmin-pack/unix/ext.ml b/src/irmin-pack/unix/ext.ml index 8f52c1dd0e..5284e962eb 100644 --- a/src/irmin-pack/unix/ext.ml +++ b/src/irmin-pack/unix/ext.ml @@ -187,7 +187,7 @@ module Maker (Config : Conf.S) = struct | (`File | `Other), _ -> Errs.raise_error (`Not_a_directory root) in let dict = Dict.v fm |> Errs.raise_if_error in - let dispatcher = Dispatcher.v ~root fm |> Errs.raise_if_error in + let dispatcher = Dispatcher.v fm |> Errs.raise_if_error in let contents = Contents.CA.v ~config ~fm ~dict ~dispatcher in let node = Node.CA.v ~config ~fm ~dict ~dispatcher in let commit = Commit.CA.v ~config ~fm ~dict ~dispatcher in diff --git a/src/irmin-pack/unix/gc.ml b/src/irmin-pack/unix/gc.ml index d92f20c108..006b789e90 100644 --- a/src/irmin-pack/unix/gc.ml +++ b/src/irmin-pack/unix/gc.ml @@ -163,7 +163,7 @@ module Worker = struct Fm.close fm |> Errs.log_if_error "GC: Close File_manager") @@ fun () -> let dict = Dict.v fm |> Errs.raise_if_error in - let dispatcher = Dispatcher.v ~root fm |> Errs.raise_if_error in + let dispatcher = Dispatcher.v fm |> Errs.raise_if_error in let node_store = Node_store.v ~config ~fm ~dict ~dispatcher in let commit_store = Commit_store.v ~config ~fm ~dict ~dispatcher in diff --git a/src/irmin-pack/unix/snapshot.ml b/src/irmin-pack/unix/snapshot.ml index 14aec2a9fc..b322591109 100644 --- a/src/irmin-pack/unix/snapshot.ml +++ b/src/irmin-pack/unix/snapshot.ml @@ -60,10 +60,7 @@ module Make (Args : Args) = struct files: suffix and control. We just open the file manager for simplicity. *) let fm = Fm.open_ro config |> Fm.Errs.raise_if_error in - let dispatcher = - let root = Conf.root config in - Dispatcher.v ~root fm |> Fm.Errs.raise_if_error - in + let dispatcher = Dispatcher.v fm |> Fm.Errs.raise_if_error in let log_size = Conf.index_log_size config in { fm; dispatcher; log_size; inode_pack; contents_pack } diff --git a/test/irmin-pack/common.ml b/test/irmin-pack/common.ml index cfcb2b927f..34518368a1 100644 --- a/test/irmin-pack/common.ml +++ b/test/irmin-pack/common.ml @@ -153,7 +153,7 @@ struct let f = ref (fun () -> ()) in let config = config ~readonly ~fresh name in let fm = get_fm config in - let dispatcher = Dispatcher.v ~root:name fm |> Errs.raise_if_error in + let dispatcher = Dispatcher.v fm |> Errs.raise_if_error in (* open the index created by the fm. *) let index = File_manager.index fm in let dict = Dict.v fm |> Errs.raise_if_error in diff --git a/test/irmin-pack/test_inode.ml b/test/irmin-pack/test_inode.ml index 444b3a50e7..271c0a0c67 100644 --- a/test/irmin-pack/test_inode.ml +++ b/test/irmin-pack/test_inode.ml @@ -120,7 +120,7 @@ struct let config = config ~indexing_strategy ~readonly:false ~fresh:true root in let fm = get_fm config in let dict = Dict.v fm |> Errs.raise_if_error in - let dispatcher = Dispatcher.v ~root fm |> Errs.raise_if_error in + let dispatcher = Dispatcher.v fm |> Errs.raise_if_error in let store = Inode.v ~config ~fm ~dict ~dispatcher in let store_contents = Contents_store.v ~config ~fm ~dict ~dispatcher in let+ foo, bar = From f992a5f7162da4fd29c18937351036cde25e863f Mon Sep 17 00:00:00 2001 From: gwenaelle Date: Wed, 21 Sep 2022 17:58:39 +0200 Subject: [PATCH 2/5] irmin-pack: Use mapping_file & poff in sequential accessors --- src/irmin-pack/unix/dispatcher.ml | 139 +++++++++++++------------ src/irmin-pack/unix/dispatcher_intf.ml | 44 +++----- 2 files changed, 84 insertions(+), 99 deletions(-) diff --git a/src/irmin-pack/unix/dispatcher.ml b/src/irmin-pack/unix/dispatcher.ml index 83710093dd..efc8a641e4 100644 --- a/src/irmin-pack/unix/dispatcher.ml +++ b/src/irmin-pack/unix/dispatcher.ml @@ -251,76 +251,79 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : if new_len > a.len then failwith "shrink_accessor_exn to larger accessor"; { a with len = new_len } - module Sequential = struct - let create_accessor_exn prefix_len suffix_len ~off ~len = + let create_sequential_accessor_exn location rem_len ~poff ~len = + if len > rem_len then raise (Errors.Pack_error `Read_out_of_bounds) + else { poff; len; location } + + let create_sequential_accessor_from_range_exn location rem_len ~poff ~min_len + ~max_len = + let len = + if rem_len < min_len then raise (Errors.Pack_error `Read_out_of_bounds) + else if rem_len > max_len then max_len + else rem_len + in + { poff; len; location } + + let create_sequential_accessor_seq t ~min_header_len ~max_header_len ~read_len + = + let chunks = + match Fm.mapping t.fm with + | Some mapping -> + let chunks = ref [] in + Mapping_file.iter mapping (fun ~off ~len -> + chunks := (off, len) :: !chunks) + |> Errs.raise_if_error; + List.rev !chunks + | None -> [] + in + let suffix_end_offset = Fm.Suffix.end_offset (Fm.suffix t.fm) in + let entry_offset_suffix_start = entry_offset_suffix_start t in + let buf = Bytes.create max_header_len in + let rec suffix_accessors poff () = + let open Seq in let open Int63.Syntax in - if off >= prefix_len then - let off = off - prefix_len in - let entry_end_offset = off + Int63.of_int len in - if entry_end_offset > suffix_len then - raise (Errors.Pack_error `Read_out_of_bounds) - else { poff = off; len; location = Suffix } + if poff >= suffix_end_offset then Nil else - let entry_end_offset = off + Int63.of_int len in - if entry_end_offset > prefix_len then - raise (Errors.Pack_error `Read_out_of_bounds) - else { poff = off; len; location = Prefix } - - let create_accessor_from_range_exn prefix_len suffix_len ~off ~min_len - ~max_len = - let open Int63.Syntax in - if off >= prefix_len then - let off = off - prefix_len in - let max_entry_len = suffix_len - off in - let len = - let min_len = Int63.of_int min_len in - let max_len = Int63.of_int max_len in - if suffix_len < min_len then - raise (Errors.Pack_error `Read_out_of_bounds) - else if max_entry_len > max_len then max_len - else max_entry_len + let rem_len = Int63.to_int (suffix_end_offset - poff) in + let accessor = + create_sequential_accessor_from_range_exn Suffix rem_len ~poff + ~min_len:min_header_len ~max_len:max_header_len in - let len = Int63.to_int len in - { poff = off; len; location = Suffix } - else - let max_entry_len = prefix_len - off in - let len = - let min_len = Int63.of_int min_len in - let max_len = Int63.of_int max_len in - if prefix_len < min_len then - raise (Errors.Pack_error `Read_out_of_bounds) - else if max_entry_len > max_len then max_len - else max_entry_len + read_exn t accessor buf; + let entry_len = read_len buf in + let r = + ( entry_offset_suffix_start + poff, + create_sequential_accessor_exn Suffix rem_len ~poff ~len:entry_len + ) in - let len = Int63.to_int len in - { poff = off; len; location = Prefix } - - let create_accessor_seq t ~min_header_len ~max_header_len ~read_len = - let open Int63.Syntax in - let buf = Bytes.create max_header_len in - let prefix_len = - match Fm.prefix t.fm with - | Some prefix -> ( - match Io.read_size prefix with - | Ok len -> len - | Error _ -> Int63.zero) - | None -> Int63.zero - in - let suffix_len = Fm.Suffix.end_offset (Fm.suffix t.fm) in - let end_offset = prefix_len + suffix_len in - let f off = - if off < end_offset then ( - let accessor = - create_accessor_from_range_exn prefix_len suffix_len ~off - ~min_len:min_header_len ~max_len:max_header_len - in - read_exn t accessor buf; - let len = read_len buf in - Some - ( (off, create_accessor_exn prefix_len suffix_len ~off ~len), - Int63.(add off (of_int len)) )) - else None - in - Seq.unfold f Int63.zero - end + let poff = poff + Int63.of_int entry_len in + let f = suffix_accessors poff in + Cons (r, f) + in + let rec prefix_accessors poff acc () = + let open Seq in + match acc with + | [] -> suffix_accessors Int63.zero () + | (off, rem_len) :: acc -> + if rem_len <= 0 then prefix_accessors poff acc () + else + let accessor = + create_sequential_accessor_from_range_exn Prefix rem_len ~poff + ~min_len:min_header_len ~max_len:max_header_len + in + read_exn t accessor buf; + let entry_len = read_len buf in + let r = + ( off, + create_sequential_accessor_exn Prefix rem_len ~poff + ~len:entry_len ) + in + let rem_len = rem_len - entry_len in + let open Int63.Syntax in + let poff = poff + Int63.of_int entry_len in + let off = off + Int63.of_int entry_len in + let f = prefix_accessors poff ((off, rem_len) :: acc) in + Cons (r, f) + in + prefix_accessors Int63.zero chunks end diff --git a/src/irmin-pack/unix/dispatcher_intf.ml b/src/irmin-pack/unix/dispatcher_intf.ml index 0835f5b8a4..d04241db18 100644 --- a/src/irmin-pack/unix/dispatcher_intf.ml +++ b/src/irmin-pack/unix/dispatcher_intf.ml @@ -50,37 +50,19 @@ module type S = sig (** [shrink_accessor_exn a ~new_len] is [a] where the length is smaller than in [a].*) - module Sequential : sig - val create_accessor_exn : int63 -> int63 -> off:int63 -> len:int -> accessor - (** [create_accessor_exn prefix_len suffix_len ~off ~len] returns an - accessor if [off] and [len] designate a readable area of the pack - files, otherwise it raises one of [Errors.Pack_error `Read_out_of_bounds]. - [prefix_len] and [suffix_len] are directly given to the function as they - are computed by costly functions to call. - In the contrary of the above create_accessor_exn function, it does not - take "virtual" lengths (aka. lengths taking gc'ed chunks into account), - but physical lengths in argument. *) - - val create_accessor_from_range_exn : - int63 -> int63 -> off:int63 -> min_len:int -> max_len:int -> accessor - (** [create_accessor_from_range_exn] is similar to - [create_accessor_exn] except that the precise length of the span will be - decided during the call. *) - - val create_accessor_seq : - t -> - min_header_len:int -> - max_header_len:int -> - read_len:(bytes -> int) -> - (int63 * accessor) Seq.t - (** [create_accessor_seq ~min_header_len ~max_header_len ~read_len] - returns a sequence of accessors, which simulates iterating sequentially - trough the entries of a pack file. [min_header_len] & [max_header_len] - represents the minimum & maximum lengths required to read the header of - an entry. [read_len] will then be called with a buffer containing the - header of the entry and should return the total length of the entry (the - length of he header plus the length of the payload)*) - end + val create_sequential_accessor_seq : + t -> + min_header_len:int -> + max_header_len:int -> + read_len:(bytes -> int) -> + (int63 * accessor) Seq.t + (** [create_sequential_accessor_seq ~min_header_len ~max_header_len ~read_len] + returns a sequence of accessors, which simulates iterating sequentially + trough the entries of a pack file. [min_header_len] & [max_header_len] + represents the minimum & maximum lengths required to read the header of an + entry. [read_len] will then be called with a buffer containing the header + of the entry and should return the total length of the entry (the length + of he header plus the length of the payload)*) val read_exn : t -> accessor -> bytes -> unit (** [read_exn] either reads in the prefix or the suffix file, depending on From 615da877b37d5e46f49aa2c1c321fe7cd01dc1e4 Mon Sep 17 00:00:00 2001 From: gwenaelle Date: Thu, 22 Sep 2022 13:57:29 +0200 Subject: [PATCH 3/5] irmin-pack: Factorize seq accessors --- src/irmin-pack/unix/dispatcher.ml | 35 ++++++++++++------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/irmin-pack/unix/dispatcher.ml b/src/irmin-pack/unix/dispatcher.ml index efc8a641e4..4bb23ec2cf 100644 --- a/src/irmin-pack/unix/dispatcher.ml +++ b/src/irmin-pack/unix/dispatcher.ml @@ -279,23 +279,23 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : let suffix_end_offset = Fm.Suffix.end_offset (Fm.suffix t.fm) in let entry_offset_suffix_start = entry_offset_suffix_start t in let buf = Bytes.create max_header_len in + let get_entry_accessor rem_len location poff = + let accessor = + create_sequential_accessor_from_range_exn location rem_len ~poff + ~min_len:min_header_len ~max_len:max_header_len + in + read_exn t accessor buf; + let entry_len = read_len buf in + entry_len, create_sequential_accessor_exn location rem_len ~poff ~len:entry_len + in let rec suffix_accessors poff () = let open Seq in let open Int63.Syntax in if poff >= suffix_end_offset then Nil else let rem_len = Int63.to_int (suffix_end_offset - poff) in - let accessor = - create_sequential_accessor_from_range_exn Suffix rem_len ~poff - ~min_len:min_header_len ~max_len:max_header_len - in - read_exn t accessor buf; - let entry_len = read_len buf in - let r = - ( entry_offset_suffix_start + poff, - create_sequential_accessor_exn Suffix rem_len ~poff ~len:entry_len - ) - in + let entry_len, accessor = get_entry_accessor rem_len Suffix poff in + let r = entry_offset_suffix_start + poff, accessor in let poff = poff + Int63.of_int entry_len in let f = suffix_accessors poff in Cons (r, f) @@ -307,17 +307,8 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : | (off, rem_len) :: acc -> if rem_len <= 0 then prefix_accessors poff acc () else - let accessor = - create_sequential_accessor_from_range_exn Prefix rem_len ~poff - ~min_len:min_header_len ~max_len:max_header_len - in - read_exn t accessor buf; - let entry_len = read_len buf in - let r = - ( off, - create_sequential_accessor_exn Prefix rem_len ~poff - ~len:entry_len ) - in + let entry_len, accessor = get_entry_accessor rem_len Suffix poff in + let r = off, accessor in let rem_len = rem_len - entry_len in let open Int63.Syntax in let poff = poff + Int63.of_int entry_len in From 317b11244ee081231725312897fed7141dcf7cef Mon Sep 17 00:00:00 2001 From: gwenaelle Date: Thu, 22 Sep 2022 14:17:39 +0200 Subject: [PATCH 4/5] irmin-pack: Rename chunks for prefix_chunks & fmt --- src/irmin-pack/unix/dispatcher.ml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/irmin-pack/unix/dispatcher.ml b/src/irmin-pack/unix/dispatcher.ml index 4bb23ec2cf..6b4931347c 100644 --- a/src/irmin-pack/unix/dispatcher.ml +++ b/src/irmin-pack/unix/dispatcher.ml @@ -266,14 +266,14 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : let create_sequential_accessor_seq t ~min_header_len ~max_header_len ~read_len = - let chunks = + let preffix_chunks = match Fm.mapping t.fm with | Some mapping -> - let chunks = ref [] in + let preffix_chunks = ref [] in Mapping_file.iter mapping (fun ~off ~len -> - chunks := (off, len) :: !chunks) + preffix_chunks := (off, len) :: !preffix_chunks) |> Errs.raise_if_error; - List.rev !chunks + List.rev !preffix_chunks | None -> [] in let suffix_end_offset = Fm.Suffix.end_offset (Fm.suffix t.fm) in @@ -286,7 +286,8 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : in read_exn t accessor buf; let entry_len = read_len buf in - entry_len, create_sequential_accessor_exn location rem_len ~poff ~len:entry_len + ( entry_len, + create_sequential_accessor_exn location rem_len ~poff ~len:entry_len ) in let rec suffix_accessors poff () = let open Seq in @@ -295,7 +296,7 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : else let rem_len = Int63.to_int (suffix_end_offset - poff) in let entry_len, accessor = get_entry_accessor rem_len Suffix poff in - let r = entry_offset_suffix_start + poff, accessor in + let r = (entry_offset_suffix_start + poff, accessor) in let poff = poff + Int63.of_int entry_len in let f = suffix_accessors poff in Cons (r, f) @@ -308,7 +309,7 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : if rem_len <= 0 then prefix_accessors poff acc () else let entry_len, accessor = get_entry_accessor rem_len Suffix poff in - let r = off, accessor in + let r = (off, accessor) in let rem_len = rem_len - entry_len in let open Int63.Syntax in let poff = poff + Int63.of_int entry_len in @@ -316,5 +317,5 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : let f = prefix_accessors poff ((off, rem_len) :: acc) in Cons (r, f) in - prefix_accessors Int63.zero chunks + prefix_accessors Int63.zero preffix_chunks end From 4c6ddcc489fef98442a48d5b0952b711bcdd5c52 Mon Sep 17 00:00:00 2001 From: gwenaelle Date: Thu, 22 Sep 2022 16:37:17 +0200 Subject: [PATCH 5/5] irmin-pack: Create buffer every time in seq accessor --- src/irmin-pack/unix/dispatcher.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irmin-pack/unix/dispatcher.ml b/src/irmin-pack/unix/dispatcher.ml index 6b4931347c..81028e99fe 100644 --- a/src/irmin-pack/unix/dispatcher.ml +++ b/src/irmin-pack/unix/dispatcher.ml @@ -278,12 +278,12 @@ module Make (Fm : File_manager.S with module Io = Io.Unix) : in let suffix_end_offset = Fm.Suffix.end_offset (Fm.suffix t.fm) in let entry_offset_suffix_start = entry_offset_suffix_start t in - let buf = Bytes.create max_header_len in let get_entry_accessor rem_len location poff = let accessor = create_sequential_accessor_from_range_exn location rem_len ~poff ~min_len:min_header_len ~max_len:max_header_len in + let buf = Bytes.create max_header_len in read_exn t accessor buf; let entry_len = read_len buf in ( entry_len,