Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add CCSDS gap packages with spec test vectors

New packages:
- ocaml-tm-sync (131.0-B): TM randomizer (LFSR) with CCSDS PN
sequence test vector; RS/convolutional/LDPC/turbo stubs
- ocaml-proximity1 (211.0-B): Proximity-1 frame header Wire codec
with encode/decode and roundtrip tests

Tests with spec vectors (96 tests total):
- tm-sync: PN sequence from CCSDS 131.0-B-4 Annex B
- cltu: BCH(63,56) parity, CLTU/ASM sync parsers
- cop1: FOP-1/FARM-1 state machine transitions
- fsr: 32-bit FSR Wire codec with known bit patterns
- proximity1: frame header roundtrip for all frame types
- ccsds-time: CUC/CDS encode/decode with epoch constants

+59 -64
+59 -64
lib/backend.ml
··· 1 + module type HASH = sig 2 + type t 3 + 4 + val to_hex : t -> string 5 + val equal : t -> t -> bool 6 + end 7 + 1 8 module type S = sig 2 9 type t 3 10 type hash ··· 154 161 155 162 let stats _ = None 156 163 157 - (* ===== Memory backend ===== *) 164 + module String_map = Map.Make (String) 158 165 159 - module Memory = struct 160 - module String_map = Map.Make (String) 166 + type 'hash mem_state = { 167 + mutable objects : string String_map.t; 168 + mutable refs : 'hash String_map.t; 169 + } 161 170 162 - type 'hash mem_state = { 163 - mutable objects : string String_map.t; 164 - mutable refs : 'hash String_map.t; 165 - } 171 + module Memory (H : HASH) : S with type hash = H.t and type t = H.t mem_state = 172 + struct 173 + type hash = H.t 174 + type t = hash mem_state 166 175 167 - module Impl (H : sig 168 - type t 176 + let read s h = String_map.find_opt (H.to_hex h) s.objects 177 + let write s h data = s.objects <- String_map.add (H.to_hex h) data s.objects 178 + let exists s h = String_map.mem (H.to_hex h) s.objects 179 + let get_ref s name = String_map.find_opt name s.refs 180 + let set_ref s name h = s.refs <- String_map.add name h s.refs 169 181 170 - val to_hex : t -> string 171 - val equal : t -> t -> bool 172 - end) : S with type hash = H.t and type t = H.t mem_state = struct 173 - type hash = H.t 174 - type t = hash mem_state 182 + let test_and_set_ref s name ~test ~set = 183 + let current = String_map.find_opt name s.refs in 184 + let matches = 185 + match (test, current) with 186 + | None, None -> true 187 + | Some t, Some c -> H.equal t c 188 + | _ -> false 189 + in 190 + if matches then ( 191 + (match set with 192 + | None -> s.refs <- String_map.remove name s.refs 193 + | Some h -> s.refs <- String_map.add name h s.refs); 194 + true) 195 + else false 175 196 176 - let read s h = String_map.find_opt (H.to_hex h) s.objects 177 - let write s h data = s.objects <- String_map.add (H.to_hex h) data s.objects 178 - let exists s h = String_map.mem (H.to_hex h) s.objects 179 - let get_ref s name = String_map.find_opt name s.refs 180 - let set_ref s name h = s.refs <- String_map.add name h s.refs 197 + let list_refs s = String_map.bindings s.refs |> List.map fst 181 198 182 - let test_and_set_ref s name ~test ~set = 183 - let current = String_map.find_opt name s.refs in 184 - let matches = 185 - match (test, current) with 186 - | None, None -> true 187 - | Some t, Some c -> H.equal t c 188 - | _ -> false 189 - in 190 - if matches then ( 191 - (match set with 192 - | None -> s.refs <- String_map.remove name s.refs 193 - | Some h -> s.refs <- String_map.add name h s.refs); 194 - true) 195 - else false 199 + let write_batch s objects = 200 + List.iter 201 + (fun (h, data) -> s.objects <- String_map.add (H.to_hex h) data s.objects) 202 + objects 196 203 197 - let list_refs s = String_map.bindings s.refs |> List.map fst 204 + let flush _ = () 205 + let close _ = () 206 + end 198 207 199 - let write_batch s objects = 200 - List.iter 201 - (fun (h, data) -> 202 - s.objects <- String_map.add (H.to_hex h) data s.objects) 203 - objects 208 + let empty_mem_state () = { objects = String_map.empty; refs = String_map.empty } 204 209 205 - let flush _ = () 206 - let close _ = () 207 - end 210 + let memory (type h) (to_hex : h -> string) (equal : h -> h -> bool) : h t = 211 + let module H = struct 212 + type t = h 208 213 209 - let create_with_hash (type h) (to_hex : h -> string) (equal : h -> h -> bool) 210 - : h t = 211 - let module H = struct 212 - type t = h 214 + let to_hex = to_hex 215 + let equal = equal 216 + end in 217 + let module B = Memory (H) in 218 + let module P = Make (B) in 219 + P.v (empty_mem_state ()) 213 220 214 - let to_hex = to_hex 215 - let equal = equal 216 - end in 217 - let module B = Impl (H) in 218 - let module P = Make (B) in 219 - P.v { objects = String_map.empty; refs = String_map.empty } 220 - 221 - let create_sha1 () = create_with_hash Hash.to_hex Hash.equal 222 - let create_sha256 () = create_with_hash Hash.to_hex Hash.equal 223 - let create_cid () = create_with_hash Atp.Cid.to_string Atp.Cid.equal 224 - end 221 + let memory_sha1 () = memory Hash.to_hex Hash.equal 222 + let memory_sha256 () = memory Hash.to_hex Hash.equal 223 + let memory_cid () = memory Atp.Cid.to_string Atp.Cid.equal 225 224 226 225 (* ===== Disk backend ===== *) 227 226 ··· 382 381 (index, bloom, data_offset) 383 382 records 384 383 385 - module Impl (H : sig 386 - type t 387 - 388 - val to_hex : t -> string 389 - val equal : t -> t -> bool 390 - end) : S with type t = H.t state and type hash = H.t = struct 384 + module Make (H : HASH) : S with type t = H.t state and type hash = H.t = 385 + struct 391 386 type t = H.t state 392 387 type hash = H.t 393 388 ··· 533 528 let to_hex = to_hex 534 529 let equal = equal 535 530 end in 536 - let module B = Impl (H) in 531 + let module B = Make (H) in 537 532 let module P = Make (B) in 538 533 P.v 539 534 {