mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
wip: improved gc behavior for ccvector
This commit is contained in:
parent
1d589cf4ac
commit
bbdcd93417
2 changed files with 30 additions and 33 deletions
|
|
@ -22,6 +22,16 @@ type 'a vector = ('a, rw) t
|
|||
|
||||
type 'a ro_vector = ('a, ro) t
|
||||
|
||||
external as_float_arr : 'a array -> float array = "%identity"
|
||||
external as_obj_arr : 'a array -> Obj.t array = "%identity"
|
||||
|
||||
let fill_with_junk_ (a:_ array) i len : unit =
|
||||
if Obj.(tag (repr a) = double_array_tag) then (
|
||||
Array.fill (as_float_arr a) i len 0.;
|
||||
) else (
|
||||
Array.fill (as_obj_arr a) i len (Obj.repr ());
|
||||
)
|
||||
|
||||
let freeze v = {
|
||||
size=v.size;
|
||||
vec=v.vec;
|
||||
|
|
@ -37,9 +47,12 @@ let create () = {
|
|||
vec = [| |];
|
||||
}
|
||||
|
||||
let create_with ?(capacity=128) x = {
|
||||
let create_with ?(capacity=128) x =
|
||||
let vec = Array.make capacity x in
|
||||
fill_with_junk_ vec 0 capacity;
|
||||
{
|
||||
size = 0;
|
||||
vec = Array.make capacity x;
|
||||
vec
|
||||
}
|
||||
|
||||
(*$T
|
||||
|
|
@ -70,16 +83,6 @@ let init n f = {
|
|||
let array_is_empty_ v =
|
||||
Array.length v.vec = 0
|
||||
|
||||
external as_float_arr : 'a array -> float array = "%identity"
|
||||
external as_obj_arr : 'a array -> Obj.t array = "%identity"
|
||||
|
||||
let fill_with_junk_ (a:_ array) i len : unit =
|
||||
if Obj.(tag (repr a) = double_array_tag) then (
|
||||
Array.fill (as_float_arr a) i len 0.;
|
||||
) else (
|
||||
Array.fill (as_obj_arr a) i len (Obj.repr ());
|
||||
)
|
||||
|
||||
(* assuming the underlying array isn't empty, resize it *)
|
||||
let resize_ v newcapacity =
|
||||
assert (newcapacity >= v.size);
|
||||
|
|
@ -146,7 +149,8 @@ let ensure_assuming_not_empty_ v ~size =
|
|||
|
||||
let ensure_with ~init v size =
|
||||
if array_is_empty_ v then (
|
||||
v.vec <- Array.make size init
|
||||
v.vec <- Array.make size init;
|
||||
fill_with_junk_ v.vec 0 size
|
||||
) else (
|
||||
ensure_assuming_not_empty_ v ~size
|
||||
)
|
||||
|
|
@ -249,7 +253,8 @@ let remove v i =
|
|||
if i < v.size - 1
|
||||
then v.vec.(i) <- v.vec.(v.size - 1);
|
||||
(* remove one element *)
|
||||
v.size <- v.size - 1
|
||||
v.size <- v.size - 1;
|
||||
fill_with_junk_ v.vec v.size 1
|
||||
|
||||
let append_seq a seq =
|
||||
seq (fun x -> push a x)
|
||||
|
|
@ -378,7 +383,8 @@ let pop_exn v =
|
|||
let new_size = v.size - 1 in
|
||||
v.size <- new_size;
|
||||
let x = v.vec.(new_size) in
|
||||
if new_size > 0 then v.vec.(new_size) <- v.vec.(0); (* free last element *)
|
||||
(* free last element *)
|
||||
fill_with_junk_ v.vec new_size 1;
|
||||
x
|
||||
|
||||
let pop v =
|
||||
|
|
@ -430,10 +436,8 @@ let shrink v n =
|
|||
let old_size = v.size in
|
||||
if n < old_size then (
|
||||
v.size <- n;
|
||||
if n > 0 then (
|
||||
(* free elements by erasing them *)
|
||||
Array.fill v.vec n (old_size-n) v.vec.(0);
|
||||
)
|
||||
fill_with_junk_ v.vec n (old_size-n);
|
||||
)
|
||||
|
||||
(*$R
|
||||
|
|
@ -611,9 +615,7 @@ let filter' p v =
|
|||
) else incr i
|
||||
done;
|
||||
(* free elements *)
|
||||
if !j > 0 && !j < v.size then (
|
||||
Array.fill v.vec !j (v.size - !j) v.vec.(0);
|
||||
);
|
||||
fill_with_junk_ v.vec !j (v.size - !j);
|
||||
v.size <- !j
|
||||
|
||||
(*$T
|
||||
|
|
@ -756,7 +758,6 @@ let filter_map f v =
|
|||
to_list (filter_map f v) = CCList.filter_map f l)
|
||||
*)
|
||||
|
||||
(* TODO: free elements *)
|
||||
let filter_map_in_place f v =
|
||||
let i = ref 0 in (* cur element *)
|
||||
let j = ref 0 in (* cur insertion point *)
|
||||
|
|
@ -772,9 +773,7 @@ let filter_map_in_place f v =
|
|||
incr j
|
||||
done;
|
||||
(* free elements *)
|
||||
if !j > 0 && !j < v.size then (
|
||||
Array.fill v.vec !j (v.size - !j) v.vec.(0);
|
||||
);
|
||||
fill_with_junk_ v.vec !j (v.size - !j);
|
||||
v.size <- !j
|
||||
|
||||
(*$QR
|
||||
|
|
|
|||
|
|
@ -35,17 +35,15 @@ val create : unit -> ('a, rw) t
|
|||
(** Create a new, empty vector. *)
|
||||
|
||||
val create_with : ?capacity:int -> 'a -> ('a, rw) t
|
||||
(** Create a new vector, using the given value as a filler.
|
||||
@param capacity the size of the underlying array.
|
||||
{b caution}: the value will likely not be GC'd before the vector is. *)
|
||||
(** Create a new vector, the value is used to enforce the type the new vector.
|
||||
@param capacity the size of the underlying array. *)
|
||||
|
||||
val return : 'a -> ('a, 'mut) t
|
||||
(** Singleton vector.
|
||||
@since 0.14 *)
|
||||
|
||||
val make : int -> 'a -> ('a, 'mut) t
|
||||
(** [make n x] makes a vector of size [n], filled with [x].
|
||||
The element [x] will possibly live as long as the vector. *)
|
||||
(** [make n x] makes a vector of size [n], filled with [x]. *)
|
||||
|
||||
val init : int -> (int -> 'a) -> ('a, 'mut) t
|
||||
(** Init the vector with the given function and size. *)
|
||||
|
|
@ -60,8 +58,8 @@ val clear_and_reset : ('a, rw) t -> unit
|
|||
|
||||
val ensure_with : init:'a -> ('a, rw) t -> int -> unit
|
||||
(** Hint to the vector that it should have at least the given capacity.
|
||||
@param init if [capacity v = 0], used as a filler
|
||||
element for the underlying array (see {!create_with}).
|
||||
@param init if [capacity v = 0], used to enforce the type of the vector
|
||||
(see {!create_with}).
|
||||
@since 0.14 *)
|
||||
|
||||
val ensure : ('a, rw) t -> int -> unit
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue