コード例 #1
0
ファイル: array.c プロジェクト: armgong/julia
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);
    }
}
コード例 #2
0
ファイル: array.c プロジェクト: gajjanag/julia
void jl_array_grow_end(jl_array_t *a, size_t inc)
{
    if (a->isshared && a->how!=3) jl_error("cannot resize array with shared data");
    // optimized for the case of only growing and shrinking at the end
    size_t alen = jl_array_nrows(a);
    if ((alen + inc) > a->maxsize - a->offset) {
        size_t newlen = a->maxsize==0 ? (inc<4?4:inc) : a->maxsize*2;
        while ((alen + inc) > newlen - a->offset)
            newlen *= 2;

        newlen = limit_overallocation(a, alen, newlen, inc);
        array_resize_buffer(a, newlen, alen, a->offset);
    }
#ifdef STORE_ARRAY_LEN
    a->length += inc;
#endif
    a->nrows += inc;
}
コード例 #3
0
ファイル: array.c プロジェクト: gajjanag/julia
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;
}
コード例 #4
0
ファイル: array.c プロジェクト: armgong/julia
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);
    }
}