Skip to content

Commit

Permalink
sizehint! now supports shrinking arrays JuliaLang#2879 (JuliaLang#26201)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianisuru authored and JeffBezanson committed Mar 7, 2018
1 parent 4acc345 commit 732743f
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
46 changes: 40 additions & 6 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,29 @@ JL_DLLEXPORT void jl_array_grow_beg(jl_array_t *a, size_t inc)
jl_array_grow_at_beg(a, 0, inc, n);
}

STATIC_INLINE void jl_array_shrink(jl_array_t *a, size_t dec)
{
//if we dont manage this array return
if (a->flags.how == 0) return;

int newbytes = (a->maxsize - dec) * a->elsize;
int oldnbytes = (a->maxsize) * a->elsize;

char *originalptr = ((char*) a->data) - a->offset;
if (a->flags.how == 1) {
//this is a julia-allocated buffer that needs to be marked
}
else if (a->flags.how == 2) {
//malloc-allocated pointer this array object manages
a->data = jl_gc_managed_realloc(originalptr, newbytes, oldnbytes,
a->flags.isaligned, (jl_value_t*) a);
a->maxsize -= dec;
}
else if (a->flags.how == 3) {
//this has has a pointer to the object that owns the data
}
}

static size_t jl_array_limit_offset(jl_array_t *a, size_t offset)
{
// make sure offset doesn't grow forever due to deleting at beginning
Expand Down Expand Up @@ -1009,14 +1032,25 @@ JL_DLLEXPORT void jl_array_del_end(jl_array_t *a, size_t dec)
JL_DLLEXPORT void jl_array_sizehint(jl_array_t *a, size_t sz)
{
size_t n = jl_array_nrows(a);
if (sz <= n)
return;
size_t inc = sz - n;
jl_array_grow_end(a, inc);
a->nrows = n;

int min = a->offset + a->length;
sz = (sz < min) ? min : sz;

if (sz <= a->maxsize) {
size_t dec = a->maxsize - sz;
//if we dont save at least an eighth of maxsize then its not worth it to shrink
if (dec < a->maxsize / 8) return;
jl_array_shrink(a, dec);
}
else {
size_t inc = sz - n;
jl_array_grow_end(a, inc);

a->nrows = n;
#ifdef STORE_ARRAY_LEN
a->length = n;
a->length = n;
#endif
}
}

JL_DLLEXPORT jl_array_t *jl_array_copy(jl_array_t *ary)
Expand Down
22 changes: 22 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,28 @@ end
@test isa(reshape(s, Val(N)), Base.ReshapedArray{Int,N})
end
end
@testset "sizehint!" begin
A = zeros(40)
resize!(A, 1)
sizehint!(A, 1)
@test length(A) == 1

A = zeros(40)
resize!(A, 20)
sizehint!(A, 1)
@test length(A) == 20

A = [1:10;]
sizehint!(A, 20)
@test length(A) == length([1:10;])
@test A == [1:10;]

A = [1:10;]
resize!(A, 5)
sizehint!(A, 5)
@test length(A) == 5
@test A == [1:5;]
end
@testset "reshape with colon" begin
# Reshape with an omitted dimension
let A = range(1, stop=60, length=60)
Expand Down

0 comments on commit 732743f

Please sign in to comment.