fix(vector): free elements in more functions, add fill_empty_slots_with

see #235
This commit is contained in:
Simon Cruanes 2018-11-30 10:28:47 -06:00
parent ff58dc0b5f
commit 3b0ceb7821
2 changed files with 47 additions and 1 deletions

View file

@ -511,7 +511,6 @@ let map_in_place f v =
*) *)
(* TODO: free elements *)
let filter' p v = let filter' p v =
let i = ref 0 in (* cur element *) let i = ref 0 in (* cur element *)
let j = ref 0 in (* cur insertion point *) let j = ref 0 in (* cur insertion point *)
@ -525,6 +524,10 @@ let filter' p v =
incr j incr j
) else incr i ) else incr i
done; done;
(* free elements *)
if !j > 0 && !j < v.size then (
Array.fill v.vec !j (v.size - !j) v.vec.(0);
);
v.size <- !j v.size <- !j
(*$T (*$T
@ -682,6 +685,10 @@ let filter_map_in_place f v =
incr i; incr i;
incr j incr j
done; done;
(* free elements *)
if !j > 0 && !j < v.size then (
Array.fill v.vec !j (v.size - !j) v.vec.(0);
);
v.size <- !j v.size <- !j
(*$QR (*$QR
@ -691,6 +698,19 @@ let filter_map_in_place f v =
to_list v = CCList.filter_map f l) to_list v = CCList.filter_map f l)
*) *)
(* check it frees memory properly *)
(*$R
let s = "coucou" ^ "lol" in
let w = Weak.create 1 in
Weak.set w 0 (Some s);
let v = of_list ["a"; s] in
filter' (fun s -> String.length s <= 1) v;
assert_equal 1 (length v);
assert_equal "a" (get v 0);
Gc.major();
assert_equal None (Weak.get w 0);
*)
let flat_map f v = let flat_map f v =
let v' = create () in let v' = create () in
iter (fun x -> iter (push v') (f x)) v; iter (fun x -> iter (push v') (f x)) v;
@ -817,6 +837,25 @@ let slice_seq v start len =
let slice v = (v.vec, 0, v.size) let slice v = (v.vec, 0, v.size)
let fill_empty_slots_with v x : unit =
if capacity v > length v then (
Array.fill v.vec (length v) (capacity v - length v) x;
)
(* check it frees memory properly *)
(*$R
let s = "coucou" ^ "lol" in
let w = Weak.create 1 in
Weak.set w 0 (Some s);
let v = of_list ["a"; s] in
ignore (pop_exn v :string);
assert_equal ~printer:string_of_int 1 (length v);
assert_equal ~printer:CCFun.id "a" (get v 0);
fill_empty_slots_with v "";
Gc.major();
assert_equal None (Weak.get w 0);
*)
let (--) i j = let (--) i j =
if i>j if i>j
then init (i-j+1) (fun k -> i-k) then init (i-j+1) (fun k -> i-k)

View file

@ -275,6 +275,13 @@ val slice_seq : ('a,_) t -> int -> int -> 'a sequence
(** [slice_seq v start len] is the sequence of elements from [v.(start)] (** [slice_seq v start len] is the sequence of elements from [v.(start)]
to [v.(start+len-1)]. *) to [v.(start+len-1)]. *)
val fill_empty_slots_with : ('a, _) t -> 'a -> unit
(** [fill_empty_slots_with v x] puts [x] in the slots of [v]'s underlying
array that are not used (ie in the last [capacity v - length v] slots).
This is useful if you removed some elements from the vector and
want to be sure they can be GC'd by erasing them from the vector.
@since NEXT_RELEASE *)
val of_klist : ?init:('a, rw) t -> 'a klist -> ('a, rw) t val of_klist : ?init:('a, rw) t -> 'a klist -> ('a, rw) t
val to_klist : ('a,_) t -> 'a klist val to_klist : ('a,_) t -> 'a klist
val of_gen : ?init:('a, rw) t -> 'a gen -> ('a, rw) t val of_gen : ?init:('a, rw) t -> 'a gen -> ('a, rw) t