Source file floating_block_index.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
module Block_info = struct
type t = {
offset : int;
predecessors : Block_hash.t list;
resulting_context_hash : Context_hash.t;
}
let max_predecessors = 12
let encoded_list_size =
let r = max_predecessors * Block_hash.size in
assert (r < 1 lsl 16) ;
r
let encoded_size = 8 + 1 + encoded_list_size + Context_hash.size
let context_hash_t =
let open Repr in
map
(bytes_of (`Fixed Context_hash.size))
(fun res -> Context_hash.of_bytes_exn res)
(fun ch -> Context_hash.to_bytes ch)
let t =
let open Repr in
map
(triple int (list ~len:`Int16 Block_key.t) context_hash_t)
(fun (offset, predecessors, resulting_context_hash) ->
{offset; predecessors; resulting_context_hash})
(fun {offset; predecessors; resulting_context_hash} ->
(offset, predecessors, resulting_context_hash))
let encode v =
let bytes = Bytes.create encoded_size in
Bytes.set_int64_be bytes 0 (Int64.of_int v.offset) ;
let len = List.length v.predecessors in
Bytes.set_int8 bytes 8 len ;
List.iteri
(fun i h ->
Bytes.blit
(Block_hash.to_bytes h)
0
bytes
(8 + 1 + (i * Block_hash.size))
Block_hash.size)
v.predecessors ;
Bytes.blit
(Context_hash.to_bytes v.resulting_context_hash)
0
bytes
(encoded_size - Context_hash.size)
Context_hash.size ;
Bytes.unsafe_to_string bytes
let decode str i =
let total_size = i + encoded_size in
let current_offset = ref i in
let offset =
TzEndian.get_int64_string str !current_offset |> Int64.to_int
in
current_offset := !current_offset + 8 ;
let list_size = TzEndian.get_int8_string str !current_offset in
current_offset := !current_offset + 1 ;
let predecessors = ref [] in
let predecessors_limit = !current_offset in
current_offset := predecessors_limit + ((list_size - 1) * Block_hash.size) ;
while !current_offset >= predecessors_limit do
predecessors :=
(String.sub str !current_offset Block_hash.size
|> Block_hash.of_string_exn)
:: !predecessors ;
current_offset := !current_offset - Block_hash.size
done ;
let resulting_context_hash =
let offset = total_size - Context_hash.size in
String.sub str offset Context_hash.size |> Context_hash.of_string_exn
in
{offset; predecessors = !predecessors; resulting_context_hash}
let pp fmt v =
let open Format in
fprintf
fmt
"@[offset: %d,@ predecessors: [@[<hov>%a @]],@ resulting context hash: \
%a@]"
v.offset
(pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt " ;@,") Block_hash.pp)
v.predecessors
Context_hash.pp
v.resulting_context_hash
end
include Index_unix.Make (Block_key) (Block_info) (Index.Cache.Unbounded)
module Legacy = struct
module Legacy_block_info = struct
type t = {offset : int; predecessors : Block_hash.t list}
let t =
let open Repr in
map
(pair int (list ~len:`Int16 Block_key.t))
(fun (offset, predecessors) -> {offset; predecessors})
(fun {offset; predecessors} -> (offset, predecessors))
let max_predecessors = 12
let encoded_list_size =
let r = max_predecessors * Block_hash.size in
assert (r < 1 lsl 16) ;
r
let encoded_size = 8 + 1 + encoded_list_size
let encode v =
let bytes = Bytes.create encoded_size in
Bytes.set_int64_be bytes 0 (Int64.of_int v.offset) ;
let len = List.length v.predecessors in
Bytes.set_int8 bytes 8 len ;
List.iteri
(fun i h ->
Bytes.blit
(Block_hash.to_bytes h)
0
bytes
(8 + 1 + (i * Block_hash.size))
Block_hash.size)
v.predecessors ;
Bytes.unsafe_to_string bytes
let decode str i =
let current_offset = ref i in
let offset =
TzEndian.get_int64_string str !current_offset |> Int64.to_int
in
current_offset := !current_offset + 8 ;
let list_size = TzEndian.get_int8_string str !current_offset in
current_offset := !current_offset + 1 ;
let predecessors = ref [] in
let limit = !current_offset in
current_offset := limit + ((list_size - 1) * Block_hash.size) ;
while !current_offset >= limit do
predecessors :=
(String.sub str !current_offset Block_hash.size
|> Block_hash.of_string_exn)
:: !predecessors ;
current_offset := !current_offset - Block_hash.size
done ;
{offset; predecessors = !predecessors}
end
include
Index_unix.Make (Block_key) (Legacy_block_info) (Index.Cache.Unbounded)
end