Source file node_hash.ml
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
open Node_type
open Hash
let (^^) nh1 nh2 =
let s1 = to_strings nh1 in
let s2 = to_strings nh2 in
let l2 = match nh2 with _, s -> String.length s in
assert (0 <= l2 && l2 <= Limit.max_hash_postfix_bytes);
let c = Char.chr l2 in
s1 @ s2 @ [ String.make 1 c ]
let of_bud h = function
| None -> h.Hasher.zero
| Some hash -> h.compute ~flags:0b11 @@ to_strings hash
let of_internal h l r = h.Hasher.compute ~flags:0b00 (l ^^ r)
let of_leaf h v = h.Hasher.compute ~flags:0b10 [Value.to_string v]
let of_extender seg hp = (hp, Segment.Serialization.encode seg )
let compute hash_conf g n : (Node_type.t * Hash.t) =
let hash n = match n with
| Disk _ -> assert false
| Hash nh -> nh
| View v ->
match hash_of_view v with
| None -> assert false
| Some nh -> nh
in
let n =
Traverse.Map.map
~enter: (fun n ->
match g n with
| `Hashed (_nh, n) -> `Return n
| `Not_Hashed v -> `Continue v)
~leave: (fun ~org v ->
View (
match org, v with
| Leaf (_, i, _), Leaf (v, _, _) -> _Leaf (v, i, Hashed (of_leaf hash_conf v))
| Bud (_, i, _), Bud (None, _, _) -> _Bud (None, i, Hashed (of_bud hash_conf None))
| Bud (_, i, _), Bud (Some n, _, _) -> _Bud (Some n, i, Hashed (of_bud hash_conf (Some (hash n))))
| Internal (_, _, i, _), Internal (nl, nr, _, _) -> _Internal (nl, nr, i, Hashed (of_internal hash_conf (hash nl) (hash nr)))
| Extender (_, _, i, _), Extender (seg, n, _, _) ->
let hp, postfix = hash n in
assert (postfix = "");
_Extender (seg, n, i, Hashed hp)
| _ -> assert false))
n
in
n, hash n
let compute_without_context hash_conf n =
let f n = match n with
| Disk _ -> raise Not_found
| Hash nh -> `Hashed (nh, n)
| View v ->
match hash_of_view v with
| None -> `Not_Hashed v
| Some nh -> `Hashed (nh, n)
in
try Some (compute hash_conf f n) with Not_found -> None