Commit 5050349c authored by POTTIER Francois's avatar POTTIER Francois
Browse files

Introduce [AtomicBitSet.fold_delta] and exploit it for faster iterations over bitsets.

parent 85a8156d
Pipeline #117264 passed with stages
in 24 seconds
......@@ -134,6 +134,22 @@ let add i s =
let remove i s =
(lnot (bit i)) land s
let rec fold_delta delta f s accu =
if s = 0 then
accu
else
let x = s land (-s) in
let s = s lxor x in (* or: s - x *)
let accu = f (delta + tib x) accu in
fold_delta delta f s accu
let rec iter_delta delta f s =
if s <> 0 then
let x = s land (-s) in
let s = s lxor x in (* or: s - x *)
f (delta + tib x);
iter_delta delta f s
let rec fold f s accu =
if s = 0 then
accu
......
......@@ -18,3 +18,10 @@
val bound: int
include GSet.S with type element = int
(* [iter_delta] and [fold_delta] are slightly generalized variants of [iter]
and [fold]. They add the constant [delta] on the fly to each set element
before presenting this set element to the user function [f]. *)
val iter_delta: int -> (element -> unit) -> t -> unit
val fold_delta: int -> (element -> 'b -> 'b) -> t -> 'b -> 'b
......@@ -83,7 +83,7 @@ let fold f s accu =
accu
| D (hi, lo) ->
let accu = A.fold f lo accu in
let accu = A.fold (fun i accu -> f (i + A.bound) accu) hi accu in
let accu = A.fold_delta A.bound f hi accu in
accu
let iter f s =
......@@ -92,7 +92,7 @@ let iter f s =
()
| D (hi, lo) ->
A.iter f lo;
A.iter (fun i -> f (i + A.bound)) hi
A.iter_delta A.bound f hi
let is_singleton s =
match s with
......
......@@ -116,9 +116,9 @@ let fold f s accu =
accu
| Q (hhi, hlo, lhi, llo) ->
let accu = A.fold f llo accu in
let accu = A.fold (fun i accu -> f (i + quarter) accu) lhi accu in
let accu = A.fold (fun i accu -> f (i + middle) accu) hlo accu in
let accu = A.fold (fun i accu -> f (i + quarter3) accu) hhi accu in
let accu = A.fold_delta quarter f lhi accu in
let accu = A.fold_delta middle f hlo accu in
let accu = A.fold_delta quarter3 f hhi accu in
accu
let iter f s =
......@@ -127,9 +127,9 @@ let iter f s =
()
| Q (hhi, hlo, lhi, llo) ->
A.iter f llo;
A.iter (fun i -> f (i + quarter)) lhi;
A.iter (fun i -> f (i + middle)) hlo;
A.iter (fun i -> f (i + quarter3)) hhi
A.iter_delta quarter f lhi;
A.iter_delta middle f hlo;
A.iter_delta quarter3 f hhi
let is_singleton s =
match s with
......
......@@ -109,11 +109,7 @@ let rec fold f s accu =
| N ->
accu
| C (addr, ss, qs) ->
let accu =
A.fold (fun offset accu ->
f (addr + offset) accu
) ss accu
in
let accu = A.fold_delta addr f ss accu in
fold f qs accu
let rec iter f s =
......@@ -121,9 +117,7 @@ let rec iter f s =
| N ->
()
| C (addr, ss, qs) ->
A.iter (fun offset ->
f (addr + offset)
) ss;
A.iter_delta addr f ss;
iter f qs
let is_singleton s =
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment