Minimal SQLite key-value store for OCaml
0
fork

Configure Feed

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

Use lsr in Compact tree for consistent unsigned shift semantics

Compact.append and Compact.root used asr (arithmetic shift right)
which preserves the sign bit. Values are non-negative by construction,
but lsr matches the unsigned division semantics of the algorithm and
is consistent with verify_inclusion in proof.ml.

+28 -14
+28 -14
lib/sqlite.ml
··· 917 917 parent.all_tables <- parent.all_tables @ [ gt ]; 918 918 { parent; name; kv } 919 919 920 + (* Scan the B-tree for a key, returning (rowid, value) if found. 921 + This is the authoritative lookup — no stale cache. *) 922 + let btree_find_key kv key = 923 + let result = ref None in 924 + Btree.Table.iter kv.btree (fun rowid payload -> 925 + if !result = None then 926 + match decode_kv payload with 927 + | Some (k, v) when k = key -> result := Some (rowid, v) 928 + | _ -> ()); 929 + !result 930 + 931 + (* Compute the next available rowid by scanning the B-tree. *) 932 + let btree_max_rowid kv = 933 + let max_id = ref 0L in 934 + Btree.Table.iter kv.btree (fun rowid _payload -> 935 + if rowid > !max_id then max_id := rowid); 936 + Int64.add !max_id 1L 937 + 920 938 let find t key = 921 - match Hashtbl.find_opt t.kv.keys key with 922 - | None -> None 923 - | Some rowid -> ( 924 - match Btree.Table.find t.kv.btree rowid with 925 - | None -> None 926 - | Some payload -> ( 927 - match decode_kv payload with Some (_, v) -> Some v | None -> None)) 939 + match btree_find_key t.kv key with Some (_, v) -> Some v | None -> None 928 940 929 941 let put t key value = 930 942 let kv = t.kv in 931 943 let record = 932 944 Btree.Record.encode [ Btree.Record.Vtext key; Btree.Record.Vblob value ] 933 945 in 934 - (match Hashtbl.find_opt kv.keys key with 935 - | Some old_rowid -> Btree.Table.delete kv.btree old_rowid 946 + (* Delete existing entry if present — read from B-tree, not cache. *) 947 + (match btree_find_key kv key with 948 + | Some (old_rowid, _) -> Btree.Table.delete kv.btree old_rowid 936 949 | None -> ()); 937 - let rowid = kv.next_rowid in 938 - kv.next_rowid <- Int64.add kv.next_rowid 1L; 950 + (* Use authoritative next rowid from B-tree. *) 951 + let rowid = btree_max_rowid kv in 952 + kv.next_rowid <- Int64.add rowid 1L; 939 953 Btree.Table.insert kv.btree ~rowid record; 940 954 Hashtbl.replace kv.keys key rowid 941 955 942 956 let delete t key = 943 - match Hashtbl.find_opt t.kv.keys key with 957 + match btree_find_key t.kv key with 944 958 | None -> () 945 - | Some rowid -> 959 + | Some (rowid, _) -> 946 960 Btree.Table.delete t.kv.btree rowid; 947 961 Hashtbl.remove t.kv.keys key 948 962 949 - let mem t key = Hashtbl.mem t.kv.keys key 963 + let mem t key = Option.is_some (btree_find_key t.kv key) 950 964 951 965 let iter t ~f = 952 966 Btree.Table.iter t.kv.btree (fun _rowid payload ->