mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 03:05:29 -05:00
Update Iter.ml to use mutable fields instead of refs (#44)
Update Iter.ml to use mutable fields instead of refs
`type 'a node = Nil | Cons of 'a array * int ref * 'a node ref` was changed to `type 'a node = Nil | Cons of { a : 'a array; mutable n : int; mutable tl : 'a node }` and all functions in MList were updated accordingly
This commit is contained in:
parent
4f47de66fe
commit
92d0022079
1 changed files with 42 additions and 32 deletions
74
src/Iter.ml
74
src/Iter.ml
|
|
@ -189,63 +189,73 @@ let keep_error seq k =
|
||||||
|
|
||||||
(** Mutable unrolled list to serve as intermediate storage *)
|
(** Mutable unrolled list to serve as intermediate storage *)
|
||||||
module MList = struct
|
module MList = struct
|
||||||
type 'a node = Nil | Cons of 'a array * int ref * 'a node ref
|
type 'a node = Nil | Cons of { a : 'a array; mutable n : int; mutable tl : 'a node }
|
||||||
|
|
||||||
(* build and call callback on every element *)
|
(* build and call callback on every element *)
|
||||||
let of_iter_with seq k =
|
let of_iter_with seq k =
|
||||||
let start = ref Nil in
|
|
||||||
let chunk_size = ref 8 in
|
let chunk_size = ref 8 in
|
||||||
(* fill the list. prev: tail-reference from previous node *)
|
let acc = ref Nil in
|
||||||
let prev, cur = ref start, ref Nil in
|
let cur = ref Nil in
|
||||||
|
let tail = ref Nil in
|
||||||
|
|
||||||
|
let[@inline] replace_tail () =
|
||||||
|
match !acc with
|
||||||
|
| Nil -> acc := !cur
|
||||||
|
| _ ->
|
||||||
|
match !tail with
|
||||||
|
| Nil -> ()
|
||||||
|
| Cons r -> r.tl <- !cur
|
||||||
|
in
|
||||||
|
|
||||||
seq (fun x ->
|
seq (fun x ->
|
||||||
k x;
|
k x;
|
||||||
(* callback *)
|
(* callback *)
|
||||||
match !cur with
|
match !cur with
|
||||||
| Nil ->
|
| Nil ->
|
||||||
let n = !chunk_size in
|
let n = !chunk_size in
|
||||||
if n < 4096 then chunk_size := 2 * !chunk_size;
|
if n < 4096 then chunk_size := 2 * n;
|
||||||
cur := Cons (Array.make n x, ref 1, ref Nil)
|
cur := Cons {a=Array.make n x; n = 1; tl = Nil}
|
||||||
| Cons (a, n, next) ->
|
| Cons r ->
|
||||||
assert (!n < Array.length a);
|
assert (r.n < Array.length r.a);
|
||||||
a.(!n) <- x;
|
r.a.(r.n) <- x;
|
||||||
incr n;
|
r.n <- succ r.n;
|
||||||
if !n = Array.length a then (
|
if r.n = Array.length r.a then (
|
||||||
!prev := !cur;
|
replace_tail ();
|
||||||
prev := next;
|
tail := !cur;
|
||||||
cur := Nil
|
cur := Nil
|
||||||
));
|
));
|
||||||
!prev := !cur;
|
replace_tail ();
|
||||||
!start
|
!acc
|
||||||
|
|
||||||
let of_iter seq = of_iter_with seq (fun _ -> ())
|
let of_iter seq = of_iter_with seq (fun _ -> ())
|
||||||
|
|
||||||
let rec iter f l =
|
let rec iter f l =
|
||||||
match l with
|
match l with
|
||||||
| Nil -> ()
|
| Nil -> ()
|
||||||
| Cons (a, n, tl) ->
|
| Cons {a; n; tl} ->
|
||||||
for i = 0 to !n - 1 do
|
for i = 0 to n - 1 do
|
||||||
f a.(i)
|
f a.(i)
|
||||||
done;
|
done;
|
||||||
iter f !tl
|
iter f tl
|
||||||
|
|
||||||
let iteri f l =
|
let iteri f l =
|
||||||
let rec iteri i f l =
|
let rec iteri i f l =
|
||||||
match l with
|
match l with
|
||||||
| Nil -> ()
|
| Nil -> ()
|
||||||
| Cons (a, n, tl) ->
|
| Cons {a; n; tl} ->
|
||||||
for j = 0 to !n - 1 do
|
for j = 0 to n - 1 do
|
||||||
f (i + j) a.(j)
|
f (i + j) a.(j)
|
||||||
done;
|
done;
|
||||||
iteri (i + !n) f !tl
|
iteri (i + n) f tl
|
||||||
in
|
in
|
||||||
iteri 0 f l
|
iteri 0 f l
|
||||||
|
|
||||||
let rec iter_rev f l =
|
let rec iter_rev f l =
|
||||||
match l with
|
match l with
|
||||||
| Nil -> ()
|
| Nil -> ()
|
||||||
| Cons (a, n, tl) ->
|
| Cons {a; n; tl} ->
|
||||||
iter_rev f !tl;
|
iter_rev f tl;
|
||||||
for i = !n - 1 downto 0 do
|
for i = n - 1 downto 0 do
|
||||||
f a.(i)
|
f a.(i)
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -253,7 +263,7 @@ module MList = struct
|
||||||
let rec len acc l =
|
let rec len acc l =
|
||||||
match l with
|
match l with
|
||||||
| Nil -> acc
|
| Nil -> acc
|
||||||
| Cons (_, n, tl) -> len (acc + !n) !tl
|
| Cons {n; tl; _} -> len (acc + n) tl
|
||||||
in
|
in
|
||||||
len 0 l
|
len 0 l
|
||||||
|
|
||||||
|
|
@ -261,8 +271,8 @@ module MList = struct
|
||||||
let rec get l i =
|
let rec get l i =
|
||||||
match l with
|
match l with
|
||||||
| Nil -> raise (Invalid_argument "MList.get")
|
| Nil -> raise (Invalid_argument "MList.get")
|
||||||
| Cons (a, n, _) when i < !n -> a.(i)
|
| Cons {a; n; _} when i < n -> a.(i)
|
||||||
| Cons (_, n, tl) -> get !tl (i - !n)
|
| Cons {n; tl; _} -> get tl (i - n)
|
||||||
|
|
||||||
let to_iter l k = iter k l
|
let to_iter l k = iter k l
|
||||||
|
|
||||||
|
|
@ -273,11 +283,11 @@ module MList = struct
|
||||||
let rec get_next _ =
|
let rec get_next _ =
|
||||||
match !cur with
|
match !cur with
|
||||||
| Nil -> None
|
| Nil -> None
|
||||||
| Cons (_, n, tl) when !i = !n ->
|
| Cons {n; tl; _} when !i = n ->
|
||||||
cur := !tl;
|
cur := tl;
|
||||||
i := 0;
|
i := 0;
|
||||||
get_next arg
|
get_next arg
|
||||||
| Cons (a, _, _) ->
|
| Cons {a; _} ->
|
||||||
let x = a.(!i) in
|
let x = a.(!i) in
|
||||||
incr i;
|
incr i;
|
||||||
Some x
|
Some x
|
||||||
|
|
@ -290,8 +300,8 @@ module MList = struct
|
||||||
let rec make (l, i) () =
|
let rec make (l, i) () =
|
||||||
match l with
|
match l with
|
||||||
| Nil -> Seq.Nil
|
| Nil -> Seq.Nil
|
||||||
| Cons (_, n, tl) when i = !n -> make (!tl, 0) ()
|
| Cons {n; tl; _} when i = n -> make (tl, 0) ()
|
||||||
| Cons (a, _, _) -> Seq.Cons (a.(i), make (l, i + 1))
|
| Cons {a;_} -> Seq.Cons (a.(i), make (l, i + 1))
|
||||||
in
|
in
|
||||||
make (l, 0)
|
make (l, 0)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue