Skip to content

Commit f6575da

Browse files
committed
Hmm
1 parent 778902c commit f6575da

1 file changed

Lines changed: 50 additions & 26 deletions

File tree

lib/picos_aux.ihtbl/picos_aux_ihtbl.ml

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ type ('k, 'v) t = ('k, 'v) state Atomic.t
7777

7878
(* *)
7979

80-
let lo_buckets = 1 lsl 3
80+
let lo_buckets = 1 lsl 4
8181

8282
and hi_buckets =
8383
let mask = ceil_pow_2_minus_1 Sys.max_array_length in
8484
mask lxor (mask lsr 1)
8585

86-
let min_buckets_default = 1 lsl 4
86+
let min_buckets_default = Int.max lo_buckets (1 lsl 4)
8787
and max_buckets_default = Int.min hi_buckets (1 lsl 30)
8888

8989
let create (type k) ?hashed_type ?min_buckets ?max_buckets () =
@@ -147,8 +147,8 @@ let copy _s i live_bs past_bs =
147147

148148
let rec split hash lo live_bs high past_lo past_hi = function
149149
| Nil ->
150-
set_if_fresh live_bs lo past_lo;
151-
set_if_fresh live_bs (lo + high) past_hi
150+
set_if_fresh live_bs (lo + high) past_hi;
151+
set_if_fresh live_bs lo past_lo
152152
| Cons r ->
153153
if hash r.key land high = high then
154154
split hash lo live_bs high past_lo
@@ -173,7 +173,7 @@ let merge _s lo live_bs high past_bs =
173173
let ((Nil | Cons _) as past) = merge past_lo past_hi in
174174
set_if_fresh live_bs lo past
175175

176-
let resize s i =
176+
let resize s i_fresh =
177177
let past = s.past in
178178
if not (Past.is_size past) then
179179
let p = Past.unsafe_as_table past in
@@ -182,10 +182,23 @@ let resize s i =
182182
let past_bs = p.buckets in
183183
let past_n = Atomic_array.length past_bs in
184184
if live_n > past_n then
185-
split s (i land (past_n - 1)) s.buckets past_n p.buckets
185+
let lo = i_fresh land (past_n - lo_buckets) in
186+
let hi = lo + (lo_buckets - 1) in
187+
for i = lo to hi do
188+
split s i live_bs past_n past_bs
189+
done
186190
else if live_n < past_n then
187-
merge s (i land (live_n - 1)) s.buckets live_n p.buckets
188-
else copy s i s.buckets p.buckets
191+
let lo = i_fresh land -lo_buckets in
192+
let hi = lo + (lo_buckets - 1) in
193+
for i = lo to hi do
194+
merge s i live_bs live_n past_bs
195+
done
196+
else
197+
let lo = i_fresh land -lo_buckets in
198+
let hi = lo + (lo_buckets - 1) in
199+
for i = lo to hi do
200+
copy s i live_bs past_bs
201+
done
189202

190203
(* *)
191204

@@ -251,18 +264,26 @@ let mark_resize_finished s (p : _ Past.table) =
251264
while 0 <= !i do
252265
begin match Atomic_array.unsafe_fenceless_get p.buckets !i with
253266
| B (Frozen r) -> size := length !size r.spine
254-
| _ -> failwith "mark_resize_finished"
267+
| B Fresh -> failwith "mark_resize_finished: Fresh"
268+
| B Nil -> failwith "mark_resize_finished: Nil"
269+
| B (Cons _) -> failwith "mark_resize_finished: Cons"
255270
end;
256271
if (Sys.opaque_identity s).past != Past.of_table p then i := -2 else decr i
257272
done;
258273
if !i = -1 then s.past <- Past.of_size !size
259274

260-
let try_finish_resize (p : _ Past.table) s mask =
261-
let stride = Int64.to_int (Random.bits64 ()) lor 1 land mask in
262-
let fuel = ref 16 in
275+
let try_finish_resize (p : _ Past.table) s =
276+
let mask =
277+
Int.min (Atomic_array.length p.buckets) (Atomic_array.length s.buckets)
278+
- lo_buckets
279+
in
280+
let stride = Int64.to_int (Random.bits64 ()) lor lo_buckets land mask in
281+
let fuel = ref 8 in
263282
let i = ref stride in
264283
while !fuel > 0 do
265-
match Atomic_array.unsafe_fenceless_get s.buckets !i with
284+
match
285+
Atomic_array.unsafe_fenceless_get s.buckets (!i + (lo_buckets - 1))
286+
with
266287
| B (Nil | Cons _) ->
267288
i := (!i + stride) land mask;
268289
if !i = stride then fuel := -1
@@ -301,7 +322,7 @@ let rec adjust_size t s mask delta result =
301322
end
302323
else begin
303324
let p = Past.unsafe_as_table past in
304-
try_finish_resize p s mask
325+
try_finish_resize p s
305326
end
306327
end;
307328
result
@@ -325,17 +346,29 @@ let rec adjust_size t s mask delta result =
325346
in
326347
result
327348
else
328-
let p = Past.unsafe_as_table past in
349+
(*let p = Past.unsafe_as_table past in*)
329350
let _ : int =
330351
Atomic.fetch_and_add
331352
(Array.unsafe_get s.non_linearizable_size_delta 0)
332353
delta
333354
in
334-
try_finish_resize p s mask;
355+
(*try_finish_resize p s;*)
335356
result
336357

337358
(* *)
338359

360+
let finish_resize s (p : _ Past.table) =
361+
let n =
362+
Int.min (Atomic_array.length p.buckets) (Atomic_array.length s.buckets)
363+
in
364+
let i = ref (n - lo_buckets) in
365+
while 0 <= !i do
366+
(* TODO: early exit *)
367+
resize s !i;
368+
i := !i - lo_buckets
369+
done;
370+
mark_resize_finished s p
371+
339372
let rec clear t =
340373
let s = Atomic.get t in
341374
let past = s.past in
@@ -352,20 +385,11 @@ let rec clear t =
352385
end
353386
else
354387
let p = Past.unsafe_as_table past in
355-
let mask = Atomic_array.length s.buckets - 1 in
356-
try_finish_resize p s mask;
388+
finish_resize s p;
357389
clear t
358390

359391
(* *)
360392

361-
let finish_resize s p =
362-
let mask = Atomic_array.length s.buckets - 1 in
363-
for i = 0 to mask do
364-
(* TODO: early exit *)
365-
resize s i
366-
done;
367-
mark_resize_finished s p
368-
369393
let rec to_seq t =
370394
let s = Atomic.get t in
371395
let past = s.past in

0 commit comments

Comments
 (0)