mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
refactor flat_tbl to not store hash
This commit is contained in:
parent
edccae0c89
commit
4980d84515
2 changed files with 29 additions and 12 deletions
|
|
@ -61,6 +61,10 @@ module type S = sig
|
||||||
|
|
||||||
val stats : 'a t -> int * int * int * int * int * int
|
val stats : 'a t -> int * int * int * int * int * int
|
||||||
(** Cf Weak.S *)
|
(** Cf Weak.S *)
|
||||||
|
|
||||||
|
(**/**)
|
||||||
|
val _pp_dib : _ t -> string
|
||||||
|
(**/**)
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make(H : Hashtbl.HashedType) = struct
|
module Make(H : Hashtbl.HashedType) = struct
|
||||||
|
|
@ -74,11 +78,10 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
| Used of {
|
| Used of {
|
||||||
k: key;
|
k: key;
|
||||||
mutable v: 'a;
|
mutable v: 'a;
|
||||||
hash: int;
|
|
||||||
mutable dib: int; (* DIB: distance to initial bucket *)
|
mutable dib: int; (* DIB: distance to initial bucket *)
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_load = 0.92
|
let max_load = 0.8
|
||||||
|
|
||||||
type 'a t = {
|
type 'a t = {
|
||||||
mutable slots: 'a slot array; (* slot for index [i] *)
|
mutable slots: 'a slot array; (* slot for index [i] *)
|
||||||
|
|
@ -125,10 +128,10 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
|
|
||||||
match Array.unsafe_get slots j with
|
match Array.unsafe_get slots j with
|
||||||
| Empty ->
|
| Empty ->
|
||||||
Array.unsafe_set slots j (Used {k; v; hash=h; dib});
|
Array.unsafe_set slots j (Used {k; v; dib});
|
||||||
self.max_dib <- max dib self.max_dib
|
self.max_dib <- max dib self.max_dib
|
||||||
| Used used_j ->
|
| Used used_j ->
|
||||||
if used_j.hash = h && H.equal k used_j.k then (
|
if H.equal k used_j.k then (
|
||||||
(* same key: replace *)
|
(* same key: replace *)
|
||||||
used_j.v <- v;
|
used_j.v <- v;
|
||||||
used_j.dib <- dib;
|
used_j.dib <- dib;
|
||||||
|
|
@ -138,10 +141,10 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
(* displace element*)
|
(* displace element*)
|
||||||
let k_j = used_j.k in
|
let k_j = used_j.k in
|
||||||
let v_j = used_j.v in
|
let v_j = used_j.v in
|
||||||
let h_j = used_j.hash in
|
let h_j = H.hash k_j in
|
||||||
let dib_j = used_j.dib in
|
let dib_j = used_j.dib in
|
||||||
|
|
||||||
Array.unsafe_set slots j (Used {k;v;hash=h;dib});
|
Array.unsafe_set slots j (Used {k;v;dib});
|
||||||
self.max_dib <- max dib self.max_dib;
|
self.max_dib <- max dib self.max_dib;
|
||||||
|
|
||||||
insert_rec_ h_j k_j v_j dib_j
|
insert_rec_ h_j k_j v_j dib_j
|
||||||
|
|
@ -171,8 +174,9 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
Array.iter
|
Array.iter
|
||||||
(fun slot -> match slot with
|
(fun slot -> match slot with
|
||||||
| Empty -> ()
|
| Empty -> ()
|
||||||
| Used {k; v; hash; _} ->
|
| Used {k; v; _} ->
|
||||||
insert_ self hash k v)
|
let h = H.hash k in
|
||||||
|
insert_ self h k v)
|
||||||
old_slots;
|
old_slots;
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
@ -188,7 +192,7 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
match Array.unsafe_get slots j with
|
match Array.unsafe_get slots j with
|
||||||
| Empty -> None
|
| Empty -> None
|
||||||
| Used used_j ->
|
| Used used_j ->
|
||||||
if used_j.hash = h && H.equal used_j.k k then (
|
if H.equal used_j.k k then (
|
||||||
Some used_j.v (* found *)
|
Some used_j.v (* found *)
|
||||||
) else if dib >= max_dib then (
|
) else if dib >= max_dib then (
|
||||||
None (* no need to go further *)
|
None (* no need to go further *)
|
||||||
|
|
@ -201,7 +205,7 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
match Array.unsafe_get slots j with
|
match Array.unsafe_get slots j with
|
||||||
| Empty -> None
|
| Empty -> None
|
||||||
| Used used_j ->
|
| Used used_j ->
|
||||||
if used_j.hash = h && H.equal used_j.k k then (
|
if H.equal used_j.k k then (
|
||||||
Some used_j.v (* found *)
|
Some used_j.v (* found *)
|
||||||
) else if dib >= max_dib then (
|
) else if dib >= max_dib then (
|
||||||
None (* no need to go further *)
|
None (* no need to go further *)
|
||||||
|
|
@ -214,7 +218,7 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
(* try a direct hit first *)
|
(* try a direct hit first *)
|
||||||
begin match Array.unsafe_get slots (addr_ h n 0) with
|
begin match Array.unsafe_get slots (addr_ h n 0) with
|
||||||
| Empty -> None
|
| Empty -> None
|
||||||
| Used {k=k2; v; hash; _} when h = hash && H.equal k k2 -> Some v
|
| Used {k=k2; v; _} when H.equal k k2 -> Some v
|
||||||
| _ -> find_rec_ 1
|
| _ -> find_rec_ 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -269,7 +273,7 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
| Empty -> ()
|
| Empty -> ()
|
||||||
| _ when dib > self.max_dib -> ()
|
| _ when dib > self.max_dib -> ()
|
||||||
| Used used_j ->
|
| Used used_j ->
|
||||||
if h = used_j.hash && H.equal k used_j.k then (
|
if H.equal k used_j.k then (
|
||||||
(* found element, remove it *)
|
(* found element, remove it *)
|
||||||
Array.unsafe_set slots j Empty;
|
Array.unsafe_set slots j Empty;
|
||||||
self.size <- self.size - 1;
|
self.size <- self.size - 1;
|
||||||
|
|
@ -337,6 +341,15 @@ module Make(H : Hashtbl.HashedType) = struct
|
||||||
|
|
||||||
(* Statistics on the table *)
|
(* Statistics on the table *)
|
||||||
let stats t = (Array.length t.slots, t.size, t.size, 0, 0, 1)
|
let stats t = (Array.length t.slots, t.size, t.size, 0, 0, 1)
|
||||||
|
|
||||||
|
let _pp_dib self =
|
||||||
|
let buf = Buffer.create 32 in
|
||||||
|
Array.iter(function
|
||||||
|
| Empty -> Printf.bprintf buf "_."
|
||||||
|
| Used {dib;_} -> Printf.bprintf buf "%d." dib)
|
||||||
|
self.slots;
|
||||||
|
Printf.bprintf buf "[mdib=%d,size=%d]" self.max_dib self.size;
|
||||||
|
Buffer.contents buf
|
||||||
end
|
end
|
||||||
|
|
||||||
(*$inject
|
(*$inject
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,10 @@ module type S = sig
|
||||||
|
|
||||||
val stats : 'a t -> int * int * int * int * int * int
|
val stats : 'a t -> int * int * int * int * int * int
|
||||||
(** Cf Weak.S *)
|
(** Cf Weak.S *)
|
||||||
|
|
||||||
|
(**/**)
|
||||||
|
val _pp_dib : _ t -> string
|
||||||
|
(**/**)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Create a hashtable *)
|
(** Create a hashtable *)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue