Switch to inline records to represent bucket lists in Hashtbl.
parent
2383de557c
commit
6d36beb17a
|
@ -36,7 +36,7 @@ type ('a, 'b) t =
|
||||||
|
|
||||||
and ('a, 'b) bucketlist =
|
and ('a, 'b) bucketlist =
|
||||||
Empty
|
Empty
|
||||||
| Cons of 'a * 'b * ('a, 'b) bucketlist
|
| Cons of { key: 'a; data: 'b; rest: ('a, 'b) bucketlist }
|
||||||
|
|
||||||
(* To pick random seeds if requested *)
|
(* To pick random seeds if requested *)
|
||||||
|
|
||||||
|
@ -95,10 +95,10 @@ let resize indexfun h =
|
||||||
h.data <- ndata; (* so that indexfun sees the new bucket count *)
|
h.data <- ndata; (* so that indexfun sees the new bucket count *)
|
||||||
let rec insert_bucket = function
|
let rec insert_bucket = function
|
||||||
Empty -> ()
|
Empty -> ()
|
||||||
| Cons(key, data, rest) ->
|
| Cons{key; data; rest} ->
|
||||||
insert_bucket rest; (* preserve original order of elements *)
|
insert_bucket rest; (* preserve original order of elements *)
|
||||||
let nidx = indexfun h key in
|
let nidx = indexfun h key in
|
||||||
ndata.(nidx) <- Cons(key, data, ndata.(nidx)) in
|
ndata.(nidx) <- Cons{key; data; rest=ndata.(nidx)} in
|
||||||
for i = 0 to osize - 1 do
|
for i = 0 to osize - 1 do
|
||||||
insert_bucket odata.(i)
|
insert_bucket odata.(i)
|
||||||
done
|
done
|
||||||
|
@ -112,7 +112,7 @@ let key_index h key =
|
||||||
|
|
||||||
let add h key info =
|
let add h key info =
|
||||||
let i = key_index h key in
|
let i = key_index h key in
|
||||||
let bucket = Cons(key, info, h.data.(i)) in
|
let bucket = Cons{key; data=info; rest=h.data.(i)} in
|
||||||
h.data.(i) <- bucket;
|
h.data.(i) <- bucket;
|
||||||
h.size <- h.size + 1;
|
h.size <- h.size + 1;
|
||||||
if h.size > Array.length h.data lsl 1 then resize key_index h
|
if h.size > Array.length h.data lsl 1 then resize key_index h
|
||||||
|
@ -121,38 +121,38 @@ let remove h key =
|
||||||
let rec remove_bucket = function
|
let rec remove_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
Empty
|
Empty
|
||||||
| Cons(k, i, next) ->
|
| Cons{key=k; data=i; rest=next} ->
|
||||||
if compare k key = 0
|
if compare k key = 0
|
||||||
then begin h.size <- h.size - 1; next end
|
then begin h.size <- h.size - 1; next end
|
||||||
else Cons(k, i, remove_bucket next) in
|
else Cons{key=k; data=i; rest=remove_bucket next} in
|
||||||
let i = key_index h key in
|
let i = key_index h key in
|
||||||
h.data.(i) <- remove_bucket h.data.(i)
|
h.data.(i) <- remove_bucket h.data.(i)
|
||||||
|
|
||||||
let rec find_rec key = function
|
let rec find_rec key = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
raise Not_found
|
raise Not_found
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
if compare key k = 0 then d else find_rec key rest
|
if compare key k = 0 then d else find_rec key rest
|
||||||
|
|
||||||
let find h key =
|
let find h key =
|
||||||
match h.data.(key_index h key) with
|
match h.data.(key_index h key) with
|
||||||
| Empty -> raise Not_found
|
| Empty -> raise Not_found
|
||||||
| Cons(k1, d1, rest1) ->
|
| Cons{key=k1; data=d1; rest=rest1} ->
|
||||||
if compare key k1 = 0 then d1 else
|
if compare key k1 = 0 then d1 else
|
||||||
match rest1 with
|
match rest1 with
|
||||||
| Empty -> raise Not_found
|
| Empty -> raise Not_found
|
||||||
| Cons(k2, d2, rest2) ->
|
| Cons{key=k2; data=d2; rest=rest2} ->
|
||||||
if compare key k2 = 0 then d2 else
|
if compare key k2 = 0 then d2 else
|
||||||
match rest2 with
|
match rest2 with
|
||||||
| Empty -> raise Not_found
|
| Empty -> raise Not_found
|
||||||
| Cons(k3, d3, rest3) ->
|
| Cons{key=k3; data=d3; rest=rest3} ->
|
||||||
if compare key k3 = 0 then d3 else find_rec key rest3
|
if compare key k3 = 0 then d3 else find_rec key rest3
|
||||||
|
|
||||||
let find_all h key =
|
let find_all h key =
|
||||||
let rec find_in_bucket = function
|
let rec find_in_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
[]
|
[]
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
if compare k key = 0
|
if compare k key = 0
|
||||||
then d :: find_in_bucket rest
|
then d :: find_in_bucket rest
|
||||||
else find_in_bucket rest in
|
else find_in_bucket rest in
|
||||||
|
@ -162,16 +162,16 @@ let replace h key info =
|
||||||
let rec replace_bucket = function
|
let rec replace_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
raise_notrace Not_found
|
raise_notrace Not_found
|
||||||
| Cons(k, i, next) ->
|
| Cons{key=k; data=i; rest=next} ->
|
||||||
if compare k key = 0
|
if compare k key = 0
|
||||||
then Cons(key, info, next)
|
then Cons{key; data=info; rest=next}
|
||||||
else Cons(k, i, replace_bucket next) in
|
else Cons{key=k; data=i; rest=replace_bucket next} in
|
||||||
let i = key_index h key in
|
let i = key_index h key in
|
||||||
let l = h.data.(i) in
|
let l = h.data.(i) in
|
||||||
try
|
try
|
||||||
h.data.(i) <- replace_bucket l
|
h.data.(i) <- replace_bucket l
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
h.data.(i) <- Cons(key, info, l);
|
h.data.(i) <- Cons{key; data=info; rest=l};
|
||||||
h.size <- h.size + 1;
|
h.size <- h.size + 1;
|
||||||
if h.size > Array.length h.data lsl 1 then resize key_index h
|
if h.size > Array.length h.data lsl 1 then resize key_index h
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ let mem h key =
|
||||||
let rec mem_in_bucket = function
|
let rec mem_in_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
false
|
false
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
compare k key = 0 || mem_in_bucket rest in
|
compare k key = 0 || mem_in_bucket rest in
|
||||||
mem_in_bucket h.data.(key_index h key)
|
mem_in_bucket h.data.(key_index h key)
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ let iter f h =
|
||||||
let rec do_bucket = function
|
let rec do_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
()
|
()
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
f k d; do_bucket rest in
|
f k d; do_bucket rest in
|
||||||
let d = h.data in
|
let d = h.data in
|
||||||
for i = 0 to Array.length d - 1 do
|
for i = 0 to Array.length d - 1 do
|
||||||
|
@ -213,7 +213,7 @@ let fold f h init =
|
||||||
match b with
|
match b with
|
||||||
Empty ->
|
Empty ->
|
||||||
accu
|
accu
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
do_bucket rest (f k d accu) in
|
do_bucket rest (f k d accu) in
|
||||||
let d = h.data in
|
let d = h.data in
|
||||||
let accu = ref init in
|
let accu = ref init in
|
||||||
|
@ -231,7 +231,7 @@ type statistics = {
|
||||||
|
|
||||||
let rec bucket_length accu = function
|
let rec bucket_length accu = function
|
||||||
| Empty -> accu
|
| Empty -> accu
|
||||||
| Cons(_, _, rest) -> bucket_length (accu + 1) rest
|
| Cons{rest} -> bucket_length (accu + 1) rest
|
||||||
|
|
||||||
let stats h =
|
let stats h =
|
||||||
let mbl =
|
let mbl =
|
||||||
|
@ -320,7 +320,7 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
|
||||||
|
|
||||||
let add h key info =
|
let add h key info =
|
||||||
let i = key_index h key in
|
let i = key_index h key in
|
||||||
let bucket = Cons(key, info, h.data.(i)) in
|
let bucket = Cons{key; data=info; rest=h.data.(i)} in
|
||||||
h.data.(i) <- bucket;
|
h.data.(i) <- bucket;
|
||||||
h.size <- h.size + 1;
|
h.size <- h.size + 1;
|
||||||
if h.size > Array.length h.data lsl 1 then resize key_index h
|
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) =
|
||||||
let rec remove_bucket = function
|
let rec remove_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
Empty
|
Empty
|
||||||
| Cons(k, i, next) ->
|
| Cons{key=k; data=i; rest=next} ->
|
||||||
if H.equal k key
|
if H.equal k key
|
||||||
then begin h.size <- h.size - 1; next end
|
then begin h.size <- h.size - 1; next end
|
||||||
else Cons(k, i, remove_bucket next) in
|
else Cons{key=k; data=i; rest=remove_bucket next} in
|
||||||
let i = key_index h key in
|
let i = key_index h key in
|
||||||
h.data.(i) <- remove_bucket h.data.(i)
|
h.data.(i) <- remove_bucket h.data.(i)
|
||||||
|
|
||||||
let rec find_rec key = function
|
let rec find_rec key = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
raise Not_found
|
raise Not_found
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
if H.equal key k then d else find_rec key rest
|
if H.equal key k then d else find_rec key rest
|
||||||
|
|
||||||
let find h key =
|
let find h key =
|
||||||
match h.data.(key_index h key) with
|
match h.data.(key_index h key) with
|
||||||
| Empty -> raise Not_found
|
| Empty -> raise Not_found
|
||||||
| Cons(k1, d1, rest1) ->
|
| Cons{key=k1; data=d1; rest=rest1} ->
|
||||||
if H.equal key k1 then d1 else
|
if H.equal key k1 then d1 else
|
||||||
match rest1 with
|
match rest1 with
|
||||||
| Empty -> raise Not_found
|
| Empty -> raise Not_found
|
||||||
| Cons(k2, d2, rest2) ->
|
| Cons{key=k2; data=d2; rest=rest2} ->
|
||||||
if H.equal key k2 then d2 else
|
if H.equal key k2 then d2 else
|
||||||
match rest2 with
|
match rest2 with
|
||||||
| Empty -> raise Not_found
|
| Empty -> raise Not_found
|
||||||
| Cons(k3, d3, rest3) ->
|
| Cons{key=k3; data=d3; rest=rest3} ->
|
||||||
if H.equal key k3 then d3 else find_rec key rest3
|
if H.equal key k3 then d3 else find_rec key rest3
|
||||||
|
|
||||||
let find_all h key =
|
let find_all h key =
|
||||||
let rec find_in_bucket = function
|
let rec find_in_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
[]
|
[]
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
if H.equal k key
|
if H.equal k key
|
||||||
then d :: find_in_bucket rest
|
then d :: find_in_bucket rest
|
||||||
else find_in_bucket rest in
|
else find_in_bucket rest in
|
||||||
|
@ -370,16 +370,16 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
|
||||||
let rec replace_bucket = function
|
let rec replace_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
raise_notrace Not_found
|
raise_notrace Not_found
|
||||||
| Cons(k, i, next) ->
|
| Cons{key=k; data=i; rest=next} ->
|
||||||
if H.equal k key
|
if H.equal k key
|
||||||
then Cons(key, info, next)
|
then Cons{key; data=info; rest=next}
|
||||||
else Cons(k, i, replace_bucket next) in
|
else Cons{key = k; data=i; rest=replace_bucket next} in
|
||||||
let i = key_index h key in
|
let i = key_index h key in
|
||||||
let l = h.data.(i) in
|
let l = h.data.(i) in
|
||||||
try
|
try
|
||||||
h.data.(i) <- replace_bucket l
|
h.data.(i) <- replace_bucket l
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
h.data.(i) <- Cons(key, info, l);
|
h.data.(i) <- Cons{key; data=info; rest=l};
|
||||||
h.size <- h.size + 1;
|
h.size <- h.size + 1;
|
||||||
if h.size > Array.length h.data lsl 1 then resize key_index h
|
if h.size > Array.length h.data lsl 1 then resize key_index h
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
|
||||||
let rec mem_in_bucket = function
|
let rec mem_in_bucket = function
|
||||||
| Empty ->
|
| Empty ->
|
||||||
false
|
false
|
||||||
| Cons(k, d, rest) ->
|
| Cons{key=k; data=d; rest} ->
|
||||||
H.equal k key || mem_in_bucket rest in
|
H.equal k key || mem_in_bucket rest in
|
||||||
mem_in_bucket h.data.(key_index h key)
|
mem_in_bucket h.data.(key_index h key)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue