Skip to content

Commit 6d36beb

Browse files
committed
Switch to inline records to represent bucket lists in Hashtbl.
1 parent 2383de5 commit 6d36beb

File tree

1 file changed

+32
-32
lines changed

1 file changed

+32
-32
lines changed

stdlib/hashtbl.ml

+32-32
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type ('a, 'b) t =
3636

3737
and ('a, 'b) bucketlist =
3838
Empty
39-
| Cons of 'a * 'b * ('a, 'b) bucketlist
39+
| Cons of { key: 'a; data: 'b; rest: ('a, 'b) bucketlist }
4040

4141
(* To pick random seeds if requested *)
4242

@@ -95,10 +95,10 @@ let resize indexfun h =
9595
h.data <- ndata; (* so that indexfun sees the new bucket count *)
9696
let rec insert_bucket = function
9797
Empty -> ()
98-
| Cons(key, data, rest) ->
98+
| Cons{key; data; rest} ->
9999
insert_bucket rest; (* preserve original order of elements *)
100100
let nidx = indexfun h key in
101-
ndata.(nidx) <- Cons(key, data, ndata.(nidx)) in
101+
ndata.(nidx) <- Cons{key; data; rest=ndata.(nidx)} in
102102
for i = 0 to osize - 1 do
103103
insert_bucket odata.(i)
104104
done
@@ -112,7 +112,7 @@ let key_index h key =
112112

113113
let add h key info =
114114
let i = key_index h key in
115-
let bucket = Cons(key, info, h.data.(i)) in
115+
let bucket = Cons{key; data=info; rest=h.data.(i)} in
116116
h.data.(i) <- bucket;
117117
h.size <- h.size + 1;
118118
if h.size > Array.length h.data lsl 1 then resize key_index h
@@ -121,38 +121,38 @@ let remove h key =
121121
let rec remove_bucket = function
122122
| Empty ->
123123
Empty
124-
| Cons(k, i, next) ->
124+
| Cons{key=k; data=i; rest=next} ->
125125
if compare k key = 0
126126
then begin h.size <- h.size - 1; next end
127-
else Cons(k, i, remove_bucket next) in
127+
else Cons{key=k; data=i; rest=remove_bucket next} in
128128
let i = key_index h key in
129129
h.data.(i) <- remove_bucket h.data.(i)
130130

131131
let rec find_rec key = function
132132
| Empty ->
133133
raise Not_found
134-
| Cons(k, d, rest) ->
134+
| Cons{key=k; data=d; rest} ->
135135
if compare key k = 0 then d else find_rec key rest
136136

137137
let find h key =
138138
match h.data.(key_index h key) with
139139
| Empty -> raise Not_found
140-
| Cons(k1, d1, rest1) ->
140+
| Cons{key=k1; data=d1; rest=rest1} ->
141141
if compare key k1 = 0 then d1 else
142142
match rest1 with
143143
| Empty -> raise Not_found
144-
| Cons(k2, d2, rest2) ->
144+
| Cons{key=k2; data=d2; rest=rest2} ->
145145
if compare key k2 = 0 then d2 else
146146
match rest2 with
147147
| Empty -> raise Not_found
148-
| Cons(k3, d3, rest3) ->
148+
| Cons{key=k3; data=d3; rest=rest3} ->
149149
if compare key k3 = 0 then d3 else find_rec key rest3
150150

151151
let find_all h key =
152152
let rec find_in_bucket = function
153153
| Empty ->
154154
[]
155-
| Cons(k, d, rest) ->
155+
| Cons{key=k; data=d; rest} ->
156156
if compare k key = 0
157157
then d :: find_in_bucket rest
158158
else find_in_bucket rest in
@@ -162,32 +162,32 @@ let replace h key info =
162162
let rec replace_bucket = function
163163
| Empty ->
164164
raise_notrace Not_found
165-
| Cons(k, i, next) ->
165+
| Cons{key=k; data=i; rest=next} ->
166166
if compare k key = 0
167-
then Cons(key, info, next)
168-
else Cons(k, i, replace_bucket next) in
167+
then Cons{key; data=info; rest=next}
168+
else Cons{key=k; data=i; rest=replace_bucket next} in
169169
let i = key_index h key in
170170
let l = h.data.(i) in
171171
try
172172
h.data.(i) <- replace_bucket l
173173
with Not_found ->
174-
h.data.(i) <- Cons(key, info, l);
174+
h.data.(i) <- Cons{key; data=info; rest=l};
175175
h.size <- h.size + 1;
176176
if h.size > Array.length h.data lsl 1 then resize key_index h
177177

178178
let mem h key =
179179
let rec mem_in_bucket = function
180180
| Empty ->
181181
false
182-
| Cons(k, d, rest) ->
182+
| Cons{key=k; data=d; rest} ->
183183
compare k key = 0 || mem_in_bucket rest in
184184
mem_in_bucket h.data.(key_index h key)
185185

186186
let iter f h =
187187
let rec do_bucket = function
188188
| Empty ->
189189
()
190-
| Cons(k, d, rest) ->
190+
| Cons{key=k; data=d; rest} ->
191191
f k d; do_bucket rest in
192192
let d = h.data in
193193
for i = 0 to Array.length d - 1 do
@@ -213,7 +213,7 @@ let fold f h init =
213213
match b with
214214
Empty ->
215215
accu
216-
| Cons(k, d, rest) ->
216+
| Cons{key=k; data=d; rest} ->
217217
do_bucket rest (f k d accu) in
218218
let d = h.data in
219219
let accu = ref init in
@@ -231,7 +231,7 @@ type statistics = {
231231

232232
let rec bucket_length accu = function
233233
| Empty -> accu
234-
| Cons(_, _, rest) -> bucket_length (accu + 1) rest
234+
| Cons{rest} -> bucket_length (accu + 1) rest
235235

236236
let stats h =
237237
let mbl =
@@ -320,7 +320,7 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
320320

321321
let add h key info =
322322
let i = key_index h key in
323-
let bucket = Cons(key, info, h.data.(i)) in
323+
let bucket = Cons{key; data=info; rest=h.data.(i)} in
324324
h.data.(i) <- bucket;
325325
h.size <- h.size + 1;
326326
if h.size > Array.length h.data lsl 1 then resize key_index h
@@ -329,38 +329,38 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
329329
let rec remove_bucket = function
330330
| Empty ->
331331
Empty
332-
| Cons(k, i, next) ->
332+
| Cons{key=k; data=i; rest=next} ->
333333
if H.equal k key
334334
then begin h.size <- h.size - 1; next end
335-
else Cons(k, i, remove_bucket next) in
335+
else Cons{key=k; data=i; rest=remove_bucket next} in
336336
let i = key_index h key in
337337
h.data.(i) <- remove_bucket h.data.(i)
338338

339339
let rec find_rec key = function
340340
| Empty ->
341341
raise Not_found
342-
| Cons(k, d, rest) ->
342+
| Cons{key=k; data=d; rest} ->
343343
if H.equal key k then d else find_rec key rest
344344

345345
let find h key =
346346
match h.data.(key_index h key) with
347347
| Empty -> raise Not_found
348-
| Cons(k1, d1, rest1) ->
348+
| Cons{key=k1; data=d1; rest=rest1} ->
349349
if H.equal key k1 then d1 else
350350
match rest1 with
351351
| Empty -> raise Not_found
352-
| Cons(k2, d2, rest2) ->
352+
| Cons{key=k2; data=d2; rest=rest2} ->
353353
if H.equal key k2 then d2 else
354354
match rest2 with
355355
| Empty -> raise Not_found
356-
| Cons(k3, d3, rest3) ->
356+
| Cons{key=k3; data=d3; rest=rest3} ->
357357
if H.equal key k3 then d3 else find_rec key rest3
358358

359359
let find_all h key =
360360
let rec find_in_bucket = function
361361
| Empty ->
362362
[]
363-
| Cons(k, d, rest) ->
363+
| Cons{key=k; data=d; rest} ->
364364
if H.equal k key
365365
then d :: find_in_bucket rest
366366
else find_in_bucket rest in
@@ -370,24 +370,24 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
370370
let rec replace_bucket = function
371371
| Empty ->
372372
raise_notrace Not_found
373-
| Cons(k, i, next) ->
373+
| Cons{key=k; data=i; rest=next} ->
374374
if H.equal k key
375-
then Cons(key, info, next)
376-
else Cons(k, i, replace_bucket next) in
375+
then Cons{key; data=info; rest=next}
376+
else Cons{key = k; data=i; rest=replace_bucket next} in
377377
let i = key_index h key in
378378
let l = h.data.(i) in
379379
try
380380
h.data.(i) <- replace_bucket l
381381
with Not_found ->
382-
h.data.(i) <- Cons(key, info, l);
382+
h.data.(i) <- Cons{key; data=info; rest=l};
383383
h.size <- h.size + 1;
384384
if h.size > Array.length h.data lsl 1 then resize key_index h
385385

386386
let mem h key =
387387
let rec mem_in_bucket = function
388388
| Empty ->
389389
false
390-
| Cons(k, d, rest) ->
390+
| Cons{key=k; data=d; rest} ->
391391
H.equal k key || mem_in_bucket rest in
392392
mem_in_bucket h.data.(key_index h key)
393393

0 commit comments

Comments
 (0)