1
(* $Id: netmcore_hashtbl.ml 1574 2011-04-10 15:13:54Z gerd $ *)
3
(* Parts of the implementation are taken over from hashtbl.ml of the
7
module H = Netmcore_heap
9
type ('a, 'b, 'h) tbl =
10
{ mutable size: int; (* number of elements *)
11
mutable data: ('a, 'b) bucketlist array; (* the buckets *)
15
and ('a, 'b) bucketlist =
17
| Cons of ('a, 'b) bucketcell
19
and ('a, 'b) bucketcell =
22
mutable tail : ('a, 'b) bucketlist
25
type ('a, 'b, 'h) t = ('a, 'b, 'h) tbl H.heap
27
type ('a, 'b, 'h) t_descr = ('a, 'b, 'h) tbl H.descr
29
let descr_of_hashtbl = H.descr_of_heap
30
let hashtbl_of_descr = H.heap_of_descr
35
data = Array.make 391 Empty;
48
Array.fill tbl.data 0 (Array.length tbl.data) Empty
55
let odata = tbl.data in
56
let osize = Array.length odata in
57
let nsize = min (2 * osize + 1) Sys.max_array_length in
58
if nsize <> osize then (
59
let ndata = H.add mut (Array.create nsize Empty) in
61
let rec insert_bucket bucket =
65
insert_bucket cell.tail; (* preserve original order of elements *)
66
let nidx = (Hashtbl.hash cell.key) mod nsize in
67
let prev = ndata.(nidx) in
68
ndata.(nidx) <- bucket;
71
for i = 0 to osize - 1 do
72
insert_bucket odata.(i)
77
let add_1 tbl mut key value =
78
let i = (Hashtbl.hash key) mod (Array.length tbl.data) in
79
let cell_orig = { key = key; value = value; tail = Empty } in
80
let elem = H.add mut (Cons cell_orig) in
81
let cell = match elem with Cons c -> c | _ -> assert false in
82
cell.tail <- tbl.data.(i);
84
tbl.size <- succ tbl.size;
85
if tbl.size > Array.length tbl.data lsl 1 then resize mut tbl
91
add_1 tbl mut key value
98
let i = (Hashtbl.hash key) mod (Array.length tbl.data) in
99
let prev = ref None in
100
let cur = ref tbl.data.(i) in
101
while !cur <> Empty do
104
if compare cell.key key = 0 then (
107
tbl.data.(i) <- cell.tail
109
pcell.tail <- cell.tail
111
tbl.size <- pred tbl.size;
118
| Empty -> assert false
122
let rec find_rec key = function
126
if compare cell.key key = 0 then cell.value else find_rec key cell.tail
128
let find_quickly tbl key =
129
match tbl.data.((Hashtbl.hash key) mod (Array.length tbl.data)) with
130
Empty -> raise Not_found
132
if compare key cell1.key = 0 then cell1.value else
133
match cell1.tail with
134
Empty -> raise Not_found
136
if compare key cell2.key = 0 then cell2.value else
137
match cell2.tail with
138
Empty -> raise Not_found
140
if compare key cell3.key = 0 then cell3.value else
141
find_rec key cell3.tail
145
(* unprotected version! *)
146
find_quickly (H.root t) key
152
find_quickly (H.root t) key
159
let rec find_in_bucket key = function
163
if compare cell.key key = 0
164
then cell.value :: find_in_bucket key cell.tail
165
else find_in_bucket key cell.tail
167
let find_all_ro t key =
168
let tbl = H.root t in
171
tbl.data.((Hashtbl.hash key) mod (Array.length tbl.data))
173
let find_all_p t key f =
174
let tbl = H.root t in
180
tbl.data.((Hashtbl.hash key) mod (Array.length tbl.data))
184
let find_all_c t key =
185
find_all_p t key H.copy
187
let replace t key value =
190
let tbl = H.root t in
192
let rec replace_bucket = function
193
| Empty -> raise Not_found
195
if compare cell.key key = 0 then
196
cell.value <- H.add mut value
198
replace_bucket cell.tail in
200
let i = (Hashtbl.hash key) mod (Array.length tbl.data) in
202
replace_bucket tbl.data.(i)
205
add_1 tbl mut key value
209
try ignore(find_ro t key); true with Not_found -> false
221
let rec do_bucket = function
224
f cell.key cell.value; do_bucket cell.tail in
225
let tbl = H.root t in
227
for i = 0 to Array.length d - 1 do