Exemplo n.º 1
0
JL_DLLEXPORT void jl_array_del_end(jl_array_t *a, size_t dec)
{
    size_t n = jl_array_nrows(a);
    if (__unlikely(n < dec))
        jl_bounds_error_int((jl_value_t*)a, 0);
    if (__unlikely(a->flags.isshared))
        array_try_unshare(a);
    jl_array_del_at_end(a, n - dec, dec, n);
}
Exemplo n.º 2
0
STATIC_INLINE void jl_array_grow_at_end(jl_array_t *a, size_t idx,
                                        size_t inc, size_t n)
{
    // optimized for the case of only growing and shrinking at the end
    if (__unlikely(a->flags.isshared)) {
        if (a->flags.how != 3)
            jl_error("cannot resize array with shared data");
        if (inc == 0) {
            // If inc > 0, it will always trigger the slow path and unshare the
            // buffer
            array_try_unshare(a);
            return;
        }
    }
    size_t elsz = a->elsize;
    char *data = (char*)a->data;
    int has_gap = n > idx;
    if (__unlikely((n + inc) > a->maxsize - a->offset)) {
        size_t nb1 = idx * elsz;
        size_t nbinc = inc * elsz;
        size_t newlen = a->maxsize == 0 ? (inc < 4 ? 4 : inc) : a->maxsize * 2;
        while ((n + inc) > newlen - a->offset)
            newlen *= 2;
        newlen = limit_overallocation(a, n, newlen, inc);
        int newbuf = array_resize_buffer(a, newlen);
        char *newdata = (char*)a->data + a->offset * elsz;
        if (newbuf) {
            memcpy(newdata, data, nb1);
            if (has_gap) {
                memcpy(newdata + nb1 + nbinc, data + nb1, n * elsz - nb1);
            }
        }
        else if (has_gap) {
            memmove(newdata + nb1 + nbinc, newdata + nb1, n * elsz - nb1);
        }
        a->data = data = newdata;
    }
    else if (has_gap) {
        size_t nb1 = idx * elsz;
        memmove(data + nb1 + inc * elsz, data + nb1, n * elsz - nb1);
    }
    size_t newnrows = n + inc;
#ifdef STORE_ARRAY_LEN
    a->length = newnrows;
#endif
    a->nrows = newnrows;
    if (a->flags.ptrarray) {
        memset(data + idx * elsz, 0, inc * elsz);
    }
}
Exemplo n.º 3
0
void jl_array_del_end(jl_array_t *a, size_t dec)
{
    if (dec == 0) return;
    if (dec > a->nrows)
        jl_throw(jl_bounds_exception);
    if (a->isshared) array_try_unshare(a);
    char *ptail = (char*)a->data + (a->nrows-dec)*a->elsize;
    if (a->ptrarray)
        memset(ptail, 0, dec*a->elsize);
    else
        ptail[0] = 0;
#ifdef STORE_ARRAY_LEN
    a->length -= dec;
#endif
    a->nrows -= dec;
}
Exemplo n.º 4
0
JL_DLLEXPORT void jl_array_del_at(jl_array_t *a, ssize_t idx, size_t dec)
{
    size_t n = jl_array_nrows(a);
    size_t last = idx + dec;
    if (__unlikely(idx < 0))
        jl_bounds_error_int((jl_value_t*)a, idx + 1);
    if (__unlikely(last > n))
        jl_bounds_error_int((jl_value_t*)a, last);
    // The unsharing needs to happen before we modify the buffer
    if (__unlikely(a->flags.isshared))
        array_try_unshare(a);
    if (idx < n - last) {
        jl_array_del_at_beg(a, idx, dec, n);
    }
    else {
        jl_array_del_at_end(a, idx, dec, n);
    }
}
Exemplo n.º 5
0
void jl_array_del_end(jl_array_t *a, size_t dec)
{
    if (dec == 0) return;
    if (dec > a->nrows)
        jl_bounds_error_int((jl_value_t*)a, a->nrows - dec);
    if (a->isshared) array_try_unshare(a);
    if (a->elsize > 0) {
        char *ptail = (char*)a->data + (a->nrows-dec)*a->elsize;
        assert(ptail < (char*)a->data + (a->length*a->elsize));
        if (a->ptrarray)
            memset(ptail, 0, dec*a->elsize);
        else
            ptail[0] = 0;
    }
#ifdef STORE_ARRAY_LEN
    a->length -= dec;
#endif
    a->nrows -= dec;
}
Exemplo n.º 6
0
void jl_array_grow_beg(jl_array_t *a, size_t inc)
{
    if (inc == 0) return;
    // designed to handle the case of growing and shrinking at both ends
    if (a->isshared) array_try_unshare(a);
    size_t es = a->elsize;
    size_t incnb = inc*es;
    if (a->offset >= inc) {
        a->data = (char*)a->data - incnb;
        a->offset -= inc;
    }
    else {
        size_t alen = a->nrows;
        size_t anb = alen*es;
        if (inc > (a->maxsize-alen)/2 - (a->maxsize-alen)/20) {
            size_t newlen = a->maxsize==0 ? inc*2 : a->maxsize*2;
            while (alen+2*inc > newlen-a->offset)
                newlen *= 2;

            newlen = limit_overallocation(a, alen, newlen, 2*inc);
            size_t center = (newlen - (alen + inc))/2;
            array_resize_buffer(a, newlen, alen, center+inc);
            char *newdata = (char*)a->data - (center+inc)*es;
            if (a->ptrarray) {
                memset(newdata, 0, (center+inc)*es);
            }
            a->offset = center;
            a->data = newdata + center*es;
        }
        else {
            size_t center = (a->maxsize - (alen + inc))/2;
            char *newdata = (char*)a->data - es*a->offset + es*center;
            memmove(&newdata[incnb], a->data, anb);
            a->data = newdata;
            a->offset = center;
        }
    }
#ifdef STORE_ARRAY_LEN
    a->length += inc;
#endif
    a->nrows += inc;
}
Exemplo n.º 7
0
void jl_array_del_beg(jl_array_t *a, size_t dec)
{
    if (dec == 0) return;
    if (dec > a->nrows)
        jl_throw(jl_bounds_exception);
    if (a->isshared) array_try_unshare(a);
    size_t es = a->elsize;
    size_t nb = dec*es;
    memset(a->data, 0, nb);
    size_t offset = a->offset;
    offset += dec;
    a->data = (char*)a->data + nb;
#ifdef STORE_ARRAY_LEN
    a->length -= dec;
#endif
    a->nrows -= dec;

    // make sure offset doesn't grow forever due to deleting at beginning
    // and growing at end
    size_t newoffs = offset;
    if (offset >= 13*a->maxsize/20) {
        newoffs = 17*(a->maxsize - a->nrows)/100;
    }
#ifdef _P64
    while (newoffs > (size_t)((uint32_t)-1)) {
        newoffs = newoffs/2;
    }
#endif
    if (newoffs != offset) {
        size_t anb = a->nrows*es;
        size_t delta = (offset - newoffs)*es;
        a->data = (char*)a->data - delta;
        memmove(a->data, (char*)a->data + delta, anb);
    }
    a->offset = newoffs;
}
Exemplo n.º 8
0
STATIC_INLINE void jl_array_grow_at_beg(jl_array_t *a, size_t idx, size_t inc,
                                        size_t n)
{
    // designed to handle the case of growing and shrinking at both ends
    if (__unlikely(a->flags.isshared)) {
        if (a->flags.how != 3)
            jl_error("cannot resize array with shared data");
        if (inc == 0) {
            // If inc > 0, it will always trigger the slow path and unshare the
            // buffer
            array_try_unshare(a);
            return;
        }
    }
    size_t newnrows = n + inc;
    size_t elsz = a->elsize;
    size_t nbinc = inc * elsz;
    char *data = (char*)a->data;
    char *newdata;
    if (a->offset >= inc) {
        assert(!a->flags.isshared);
        newdata = data - nbinc;
        a->offset -= inc;
        if (idx > 0) {
            memmove(newdata, data, idx * elsz);
        }
    }
    else {
        size_t oldoffsnb = a->offset * elsz;
        size_t nb1 = idx * elsz;
        if (inc > (a->maxsize - n) / 2 - (a->maxsize - n) / 20) {
            size_t newlen = a->maxsize == 0 ? inc * 2 : a->maxsize * 2;
            while (n + 2 * inc > newlen - a->offset)
                newlen *= 2;
            newlen = limit_overallocation(a, n, newlen, 2 * inc);
            size_t newoffset = (newlen - newnrows) / 2;
            if (!array_resize_buffer(a, newlen))
                data = (char*)a->data + oldoffsnb;
            newdata = (char*)a->data + newoffset * elsz;
            // We could use memcpy if resizing allocates a new buffer,
            // hopefully it's not a particularly important optimization.
            if (idx > 0 && newdata < data)
                memmove(newdata, data, nb1);
            memmove(newdata + nbinc + nb1, data + nb1, n * elsz - nb1);
            if (idx > 0 && newdata > data)
                memmove(newdata, data, nb1);
            a->offset = newoffset;
        }
        else {
            assert(!a->flags.isshared);
            a->offset = (a->maxsize - newnrows) / 2;
            newdata = data - oldoffsnb + a->offset * elsz;
            // We could use memcpy if resizing allocates a new buffer,
            // hopefully it's not a particularly important optimization.
            if (idx > 0 && newdata < data)
                memmove(newdata, data, nb1);
            memmove(newdata + nbinc + nb1, data + nb1, n * elsz - nb1);
            if (idx > 0 && newdata > data)
                memmove(newdata, data, nb1);
        }
    }
#ifdef STORE_ARRAY_LEN
    a->length = newnrows;
#endif
    a->nrows = newnrows;
    a->data = newdata;
    if (a->flags.ptrarray) {
        memset(newdata + idx * elsz, 0, nbinc);
    }
}