@@ -60,67 +60,81 @@ let resize ~hash h =
60
60
done
61
61
end
62
62
63
-
64
- let add0 ~hash h key value =
65
- let h_buckets = C. buckets h in
66
- let h_buckets_lenth = Array. length h_buckets in
67
- let i = (Bs_Hash. getHash hash) key [@ bs] land (h_buckets_lenth - 1 ) in
68
- let bucket =
69
- N. bucket ~key ~value ~next: (Bs_Array. unsafe_get h_buckets i) in
70
- Bs_Array. unsafe_set h_buckets i (C. return bucket);
71
- let h_new_size = C. size h + 1 in
72
- C. sizeSet h h_new_size;
73
- if h_new_size > h_buckets_lenth lsl 1 then resize ~hash h
74
-
75
-
76
- let rec remove_bucket ~eq h h_buckets i key prec buckets =
77
- match C. toOpt buckets with
63
+ let rec replace_in_bucket ~eq key info cell =
64
+ if (Bs_Hash. getEq eq) (N. key cell) key [@ bs]
65
+ then
66
+ begin
67
+ N. keySet cell key;
68
+ N. valueSet cell info;
69
+ false
70
+ end
71
+ else
72
+ match C. toOpt (N. next cell) with
73
+ | None -> true
74
+ | Some cell ->
75
+ replace_in_bucket ~eq key info cell
76
+
77
+ (* if [key] already exists, replace it, otherwise add it
78
+ Here we add it to the head, it could be tail
79
+ *)
80
+ let add0 ~hash ~eq h key value =
81
+ let h_buckets = C. buckets h in
82
+ let i = (Bs_Hash. getHash hash) key [@ bs] land (Array. length h_buckets - 1 ) in
83
+ let l = Array. unsafe_get h_buckets i in
84
+ match C. toOpt l with
85
+ | None ->
86
+ Bs_Array. unsafe_set h_buckets i (C. return
87
+ (N. bucket ~key ~value ~next: l));
88
+ C. sizeSet h (C. size h + 1 );
89
+ if C. size h > Array. length (C. buckets h) lsl 1 then resize ~hash h
90
+ (* do we really need resize here ? *)
91
+ | Some bucket ->
92
+ begin
93
+ if replace_in_bucket ~eq key value bucket then begin
94
+ Bs_Array. unsafe_set h_buckets i (C. return
95
+ (N. bucket ~key ~value ~next: l));
96
+ C. sizeSet h (C. size h + 1 );
97
+ if C. size h > Array. length (C. buckets h) lsl 1 then resize ~hash h
98
+ (* TODO: duplicate bucklets ? *)
99
+ end
100
+ end
101
+
102
+ let rec remove_bucket ~eq h h_buckets i key prec bucket =
103
+ match C. toOpt bucket with
78
104
| None -> ()
79
105
| Some cell ->
80
106
let cell_next = N. next cell in
81
107
if (Bs_Hash. getEq eq) (N. key cell) key [@ bs]
82
108
then
83
- begin
84
- (match C. toOpt prec with
85
- | None -> Bs_Array. unsafe_set h_buckets i cell_next
86
- | Some c -> N. nextSet c cell_next);
109
+ begin
110
+ N. nextSet prec cell_next ;
87
111
C. sizeSet h (C. size h - 1 );
88
112
end
89
- else remove_bucket ~eq h h_buckets i key buckets cell_next
113
+ else remove_bucket ~eq h h_buckets i key cell cell_next
90
114
91
115
let remove0 ~hash ~eq h key =
92
116
let h_buckets = C. buckets h in
93
117
let i = (Bs_Hash. getHash hash) key [@ bs] land (Array. length h_buckets - 1 ) in
94
- remove_bucket ~eq h h_buckets i key C. emptyOpt (Bs_Array. unsafe_get h_buckets i)
95
-
96
- let rec removeAllBuckets ~eq h h_buckets i key prec buckets =
97
- match C. toOpt buckets with
118
+ let bucket = Bs_Array. unsafe_get h_buckets i in
119
+ match C. toOpt bucket with
98
120
| None -> ()
99
- | Some cell ->
100
- let cell_next = N. next cell in
101
- if (Bs_Hash. getEq eq) (N. key cell) key [@ bs]
102
- then
103
- begin
104
- (match C. toOpt prec with
105
- | None -> Bs_Array. unsafe_set h_buckets i cell_next
106
- | Some c -> N. nextSet c cell_next);
107
- C. sizeSet h (C. size h - 1 );
108
- end ;
109
- removeAllBuckets ~eq h h_buckets i key buckets cell_next
110
-
111
- let removeAll0 ~hash ~eq h key =
112
- let h_buckets = C. buckets h in
113
- let i = (Bs_Hash. getHash hash) key [@ bs] land (Array. length h_buckets - 1 ) in
114
- removeAllBuckets ~eq h h_buckets i key C. emptyOpt (Bs_Array. unsafe_get h_buckets i)
121
+ | Some cell ->
122
+ if (Bs_Hash. getEq eq) (N. key cell ) key [@ bs] then
123
+ begin
124
+ Bs_Array. unsafe_set h_buckets i (N. next cell);
125
+ C. sizeSet h (C. size h - 1 )
126
+ end
127
+ else
128
+ remove_bucket ~eq h h_buckets i key cell (N. next cell)
115
129
116
130
117
- let rec find_rec ~eq key buckets =
131
+ let rec findAux ~eq key buckets =
118
132
match C. toOpt buckets with
119
133
| None ->
120
134
None
121
135
| Some cell ->
122
136
if (Bs_Hash. getEq eq) key (N. key cell) [@ bs] then Some (N. value cell)
123
- else find_rec ~eq key (N. next cell)
137
+ else findAux ~eq key (N. next cell)
124
138
125
139
let findOpt0 ~hash ~eq h key =
126
140
let h_buckets = C. buckets h in
@@ -144,62 +158,24 @@ let findOpt0 ~hash ~eq h key =
144
158
(N. key cell3) [@ bs] then
145
159
Some (N. value cell3)
146
160
else
147
- find_rec ~eq key (N. next cell3)
148
-
149
-
150
- let findAll0 ~hash ~eq h key =
151
- let rec find_in_bucket buckets =
152
- match C. toOpt buckets with
153
- | None ->
154
- []
155
- | Some cell ->
156
- if (Bs_Hash. getEq eq)
157
- (N. key cell) key [@ bs]
158
- then (N. value cell) :: find_in_bucket (N. next cell)
159
- else find_in_bucket (N. next cell) in
160
- let h_buckets = C. buckets h in
161
- let nid = (Bs_Hash. getHash hash) key [@ bs] land (Array. length h_buckets - 1 ) in
162
- find_in_bucket (Bs_Array. unsafe_get h_buckets nid)
161
+ findAux ~eq key (N. next cell3)
162
+
163
+
163
164
164
- let rec replace_bucket ~eq key info buckets =
165
- match C. toOpt buckets with
166
- | None ->
167
- true
168
- | Some cell ->
169
- if (Bs_Hash. getEq eq) (N. key cell) key [@ bs]
170
- then
171
- begin
172
- N. keySet cell key;
173
- N. valueSet cell info;
174
- false
175
- end
176
- else
177
- replace_bucket ~eq key info (N. next cell)
178
165
179
- let replace0 ~hash ~eq h key info =
180
- let h_buckets = C. buckets h in
181
- let i = (Bs_Hash. getHash hash) key [@ bs] land (Array. length h_buckets - 1 ) in
182
- let l = Array. unsafe_get h_buckets i in
183
- if replace_bucket ~eq key info l then begin
184
- Bs_Array. unsafe_set h_buckets i (C. return
185
- (N. bucket ~key ~value: info ~next: l));
186
- C. sizeSet h (C. size h + 1 );
187
- if C. size h > Array. length (C. buckets h) lsl 1 then resize ~hash h
188
- (* TODO: duplicate bucklets ? *)
189
- end
190
166
191
167
let rec mem_in_bucket ~eq key cell =
192
- (Bs_Hash. getEq eq)
193
- (N. key cell) key [@ bs] ||
194
- (match C. toOpt (N. next cell) with
195
- | None -> false
196
- | Some nextCell ->
197
- mem_in_bucket ~eq key nextCell)
168
+ (Bs_Hash. getEq eq)
169
+ (N. key cell) key [@ bs] ||
170
+ (match C. toOpt (N. next cell) with
171
+ | None -> false
172
+ | Some nextCell ->
173
+ mem_in_bucket ~eq key nextCell)
198
174
199
175
let mem0 ~hash ~eq h key =
200
176
let h_buckets = C. buckets h in
201
177
let nid = (Bs_Hash. getHash hash) key [@ bs] land (Array. length h_buckets - 1 ) in
202
- let bucket = ( Bs_Array. unsafe_get h_buckets nid) in
178
+ let bucket = Bs_Array. unsafe_get h_buckets nid in
203
179
match C. toOpt bucket with
204
180
| None -> false
205
181
| Some bucket ->
@@ -214,6 +190,7 @@ let iter0 = N.iter0
214
190
let fold0 = N. fold0
215
191
let logStats0 = N. logStats0
216
192
let filterMapInplace0 = N. filterMapInplace0
193
+ let toArray0 = N. toArray0
217
194
218
195
(* Wrapper *)
219
196
let create dict initialize_size =
@@ -229,32 +206,21 @@ let logStats h = logStats0 (B.data h)
229
206
let add (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key :a ) (info :b ) =
230
207
let dict,data = B. (dict h, data h) in
231
208
let module M = (val dict) in
232
- add0 ~hash: M. hash data key info
209
+ add0 ~hash: M. hash ~eq: M. eq data key info
233
210
234
211
let remove (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key : a ) =
235
212
let dict,data = B. (dict h, data h) in
236
213
let module M = (val dict) in
237
214
remove0 ~hash: M. hash ~eq: M. eq data key
238
215
239
- let removeAll (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key : a ) =
240
- let dict,data = B. (dict h, data h) in
241
- let module M = (val dict) in
242
- removeAll0 ~hash: M. hash ~eq: M. eq data key
243
216
244
217
let findOpt (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key : a ) =
245
218
let dict,data = B. (dict h, data h) in
246
219
let module M = (val dict) in
247
220
findOpt0 ~hash: M. hash ~eq: M. eq data key
248
221
249
- let findAll (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key : a ) =
250
- let dict,data = B. (dict h, data h) in
251
- let module M = (val dict) in
252
- findAll0 ~hash: M. hash ~eq: M. eq data key
253
222
254
- let replace (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key : a ) (info : b ) =
255
- let dict,data = B. (dict h, data h) in
256
- let module M = (val dict) in
257
- replace0 ~hash: M. hash ~eq: M. eq data key info
223
+
258
224
259
225
let mem (type a ) (type b ) (type id ) (h : (a,b,id) t ) (key : a ) =
260
226
let dict,data = B. (dict h, data h) in
@@ -263,3 +229,39 @@ let mem (type a) (type b) (type id) (h : (a,b,id) t) (key : a) =
263
229
264
230
let filterMapInplace h f =
265
231
filterMapInplace0 (B. data h) f
232
+ let toArray (type a ) (type b ) (type id ) (h : (a,b,id) t ) =
233
+ toArray0 (B. data h)
234
+ let ofArray0 ~hash ~eq arr =
235
+ let len = Bs.Array. length arr in
236
+ let v = create0 len in
237
+ for i = 0 to len - 1 do
238
+ let key,value = (Bs.Array. unsafe_get arr i) in
239
+ add0 ~eq ~hash v key value
240
+ done ;
241
+ v
242
+
243
+ (* TOOD: optimize heuristics for resizing *)
244
+ let addArray0 ~hash ~eq h arr =
245
+ let len = Bs.Array. length arr in
246
+ for i = 0 to len - 1 do
247
+ let key,value = (Bs_Array. unsafe_get arr i) in
248
+ add0 h ~eq ~hash key value
249
+ done
250
+
251
+ let ofArray (type a ) (type id )
252
+ ~dict :(dict :(a,id) Bs_Hash.t ) arr =
253
+ let module M = (val dict) in
254
+ B. bag ~dict
255
+ ~data: M. (ofArray0 ~eq~hash arr)
256
+
257
+ let addArray (type a ) (type b ) (type id )
258
+ (h : (a,b,id) t ) arr =
259
+ let dict,data = B. (dict h, data h) in
260
+ let module M = (val dict) in
261
+ M. (addArray0 ~hash ~eq data arr)
262
+
263
+ let keys0 = N. keys0
264
+ let keys h =
265
+ keys0 (B. data h)
266
+ let values0 = N. values0
267
+ let values h = N. values0 (B. data h)
0 commit comments