File: storage_ancient.ml

package info (click to toggle)
ocaml-odoc 3.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,008 kB
  • sloc: ml: 60,567; javascript: 2,572; sh: 566; makefile: 31
file content (45 lines) | stat: -rw-r--r-- 1,156 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
let base_addr () =
  if Sys.word_size > 32
  then Int64.to_nativeint 0x100000000000L
  else failwith "TODO: support ancient on 32 bits"

type writer =
  { mutable write_shard : int
  ; ancient : Ancient.md
  }

let open_out filename =
  let handle = Unix.openfile filename Unix.[ O_RDWR; O_TRUNC; O_CREAT ] 0o640 in
  let ancient = Ancient.attach handle (base_addr ()) in
  { write_shard = 0; ancient }

let save ~db (t : Db.t) =
  ignore (Ancient.share db.ancient db.write_shard t) ;
  db.write_shard <- db.write_shard + 1

let close_out db = Ancient.detach db.ancient

type reader = { shards : Db.t array }

let load_shard md shard =
  match Ancient.get md shard with
  | t -> Some (Ancient.follow t)
  | exception _ -> None

let load_shards md =
  let rec go i =
    match load_shard md i with
    | None -> []
    | Some t -> t :: go (i + 1)
  in
  Array.of_list (go 0)

let db_open_in db : reader =
  let filename = db in
  let handle = Unix.openfile filename Unix.[ O_RDWR ] 0o640 in
  let md = Ancient.attach handle (base_addr ()) in
  { shards = load_shards md }

let load db_filename =
  let h = db_open_in db_filename in
  Array.to_list h.shards