mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
fix asymptotic behavior of resize functions
This commit is contained in:
parent
e6e07ba4da
commit
2c2fa5d008
1 changed files with 32 additions and 29 deletions
|
|
@ -138,9 +138,11 @@ let grow_with_ v ~filler:x =
|
||||||
Use a doubling-size strategy so that calling many times [ensure] will
|
Use a doubling-size strategy so that calling many times [ensure] will
|
||||||
behave well *)
|
behave well *)
|
||||||
let ensure_assuming_not_empty_ v ~size =
|
let ensure_assuming_not_empty_ v ~size =
|
||||||
if size > Sys.max_array_length
|
if size > Sys.max_array_length then (
|
||||||
then invalid_arg "vec.ensure: size too big"
|
invalid_arg "vec.ensure: size too big"
|
||||||
else (
|
) else if size < Array.length v.vec then (
|
||||||
|
() (* nothing to do *)
|
||||||
|
) else (
|
||||||
let n = ref (max 8 (Array.length v.vec)) in
|
let n = ref (max 8 (Array.length v.vec)) in
|
||||||
while !n < size do n := min Sys.max_array_length (2* !n) done;
|
while !n < size do n := min Sys.max_array_length (2* !n) done;
|
||||||
resize_ v !n v.vec.(0)
|
resize_ v !n v.vec.(0)
|
||||||
|
|
@ -203,19 +205,17 @@ let push v x =
|
||||||
|
|
||||||
let resize_with v f size =
|
let resize_with v f size =
|
||||||
if size<0 then invalid_arg "Vec.resize_with";
|
if size<0 then invalid_arg "Vec.resize_with";
|
||||||
let new_vec =
|
if Array.length v.vec = 0 then (
|
||||||
if size >= Array.length v.vec then
|
let new_vec = Array.init size f in
|
||||||
let new_vec = Array.make size (f 0) in
|
v.vec <- new_vec;
|
||||||
Array.blit v.vec 0 new_vec 0 v.size;
|
v.size <- size
|
||||||
new_vec
|
) else (
|
||||||
else
|
ensure_assuming_not_empty_ v size;
|
||||||
v.vec
|
for i = v.size to size - 1 do
|
||||||
in
|
Array.unsafe_set v.vec i (f i)
|
||||||
for i = v.size to size - 1 do
|
done;
|
||||||
Array.unsafe_set new_vec i (f i)
|
v.size <- size
|
||||||
done;
|
)
|
||||||
v.vec <- new_vec;
|
|
||||||
v.size <- size
|
|
||||||
|
|
||||||
(*$T
|
(*$T
|
||||||
let v = make 1 0 in resize_with v (fun i -> i) 5; to_list v = [0;1;2;3;4]
|
let v = make 1 0 in resize_with v (fun i -> i) 5; to_list v = [0;1;2;3;4]
|
||||||
|
|
@ -230,19 +230,17 @@ let resize_with v f size =
|
||||||
|
|
||||||
let resize_with_init v ~init size =
|
let resize_with_init v ~init size =
|
||||||
if size<0 then invalid_arg "Vec.resize_with_init";
|
if size<0 then invalid_arg "Vec.resize_with_init";
|
||||||
let new_vec =
|
if Array.length v.vec = 0 then (
|
||||||
if size >= Array.length v.vec then
|
let vec = Array.make size init in
|
||||||
let new_vec = Array.make size init in
|
v.vec <- vec;
|
||||||
Array.blit v.vec 0 new_vec 0 v.size;
|
v.size <- size;
|
||||||
new_vec
|
) else (
|
||||||
else
|
ensure_assuming_not_empty_ v size;
|
||||||
v.vec
|
for i = v.size to size - 1 do
|
||||||
in
|
Array.unsafe_set v.vec i init
|
||||||
for i = v.size to size - 1 do
|
done;
|
||||||
Array.unsafe_set new_vec i init
|
v.size <- size;
|
||||||
done;
|
)
|
||||||
v.vec <- new_vec;
|
|
||||||
v.size <- size
|
|
||||||
|
|
||||||
(*$T
|
(*$T
|
||||||
let v = make 1 0 in resize_with_init v ~init:1 5; to_list v = [0;1;1;1;1]
|
let v = make 1 0 in resize_with_init v ~init:1 5; to_list v = [0;1;1;1;1]
|
||||||
|
|
@ -256,6 +254,11 @@ let resize_with_init v ~init size =
|
||||||
let v = make 5 0 in resize_with_init v ~init:1 5; List.length (to_list v) = 5
|
let v = make 5 0 in resize_with_init v ~init:1 5; List.length (to_list v) = 5
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
(* test for asymptotic behavior *)
|
||||||
|
(*$T
|
||||||
|
let v =make 1 0 in for i=0 to 100_000 do resize_with_init v ~init:10 i; done; true
|
||||||
|
*)
|
||||||
|
|
||||||
(** Add all elements of b to a *)
|
(** Add all elements of b to a *)
|
||||||
let append a b =
|
let append a b =
|
||||||
if array_is_empty_ a then (
|
if array_is_empty_ a then (
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue