mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
feat(CCBV): prevent resize from shrinking underlying array
also add `BV.resize_minimize_memory` to force shrinking. This shouldn't be the default because it can allocate a lot in case of repeated shrinkings.
This commit is contained in:
parent
92463d33c5
commit
3d57a5c86e
2 changed files with 42 additions and 20 deletions
|
|
@ -165,20 +165,28 @@ let cardinal bv =
|
|||
*)
|
||||
|
||||
let really_resize_ bv ~desired ~current size =
|
||||
bv.size <- size;
|
||||
if desired <> current then (
|
||||
let b = Bytes.make desired zero in
|
||||
Bytes.blit bv.b 0 b 0 current;
|
||||
bv.b <- b;
|
||||
bv.size <- size
|
||||
)
|
||||
|
||||
let grow_ bv size =
|
||||
if size <= capacity bv (* within capacity *)
|
||||
then bv.size <- size
|
||||
else (
|
||||
let[@inline never] grow_real_ bv size =
|
||||
(* beyond capacity *)
|
||||
let desired = bytes_length_of_size size in
|
||||
let current = Bytes.length bv.b in
|
||||
assert (desired > current);
|
||||
really_resize_ bv ~desired ~current size
|
||||
|
||||
let grow_ bv size =
|
||||
if size <= capacity bv then (
|
||||
(* within capacity *)
|
||||
bv.size <- size
|
||||
) else (
|
||||
(* resize. This is a separate function so it's easier to
|
||||
inline the happy path. *)
|
||||
grow_real_ bv size
|
||||
)
|
||||
|
||||
let shrink_ bv size =
|
||||
|
|
@ -188,11 +196,19 @@ let shrink_ bv size =
|
|||
|
||||
let resize bv size =
|
||||
if size < 0 then invalid_arg "resize: negative size";
|
||||
if size < bv.size (* shrink *)
|
||||
then shrink_ bv size
|
||||
else if size = bv.size
|
||||
then ()
|
||||
else grow_ bv size
|
||||
if size < bv.size then (
|
||||
bv.size <- size;
|
||||
) else if size > bv.size then (
|
||||
grow_ bv size
|
||||
)
|
||||
|
||||
let resize_minimize_memory bv size =
|
||||
if size < 0 then invalid_arg "resize: negative size";
|
||||
if size < bv.size then (
|
||||
shrink_ bv size
|
||||
) else if size > bv.size then (
|
||||
grow_ bv size
|
||||
)
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.create ~size:87 true in
|
||||
|
|
|
|||
|
|
@ -39,10 +39,16 @@ val capacity : t -> int
|
|||
@since 1.2 *)
|
||||
|
||||
val resize : t -> int -> unit
|
||||
(** Resize the BV so that it has the specified length. This can grow or shrink
|
||||
the underlying bitvector.
|
||||
(** Resize the BV so that it has the specified length. This can grow
|
||||
the underlying array, but it will not shrink it, to minimize
|
||||
memory traffic.
|
||||
@raise Invalid_argument on negative sizes. *)
|
||||
|
||||
@raise Invalid_arg on negative sizes. *)
|
||||
val resize_minimize_memory : t -> int -> unit
|
||||
(** Same as {!resize}, but this can also shrink the underlying
|
||||
array if this reduces the size.
|
||||
@raise Invalid_argument on negative sizes.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val is_empty : t -> bool
|
||||
(** Are there any true bits? *)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue