JL_DLLEXPORT void jl_array_ptr_1d_push(jl_array_t *a, jl_value_t *item) { assert(jl_typeis(a, jl_array_any_type)); jl_array_grow_end(a, 1); size_t n = jl_array_nrows(a); jl_array_ptr_set(a, n - 1, item); }
JL_DLLEXPORT void jl_array_ptr_1d_push2(jl_array_t *a, jl_value_t *b, jl_value_t *c) { assert(jl_typeis(a, jl_array_any_type)); jl_array_grow_end(a, 2); size_t n = jl_array_nrows(a); jl_array_ptr_set(a, n - 2, b); jl_array_ptr_set(a, n - 1, c); }
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); }
static void array_try_unshare(jl_array_t *a) { if (a->isshared) { if (a->how != 3) jl_error("cannot resize array with shared data"); size_t len = jl_array_nrows(a); array_resize_buffer(a, len, len, a->offset); } }
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; #ifdef STORE_ARRAY_LEN a->length = n; #endif }
JL_DLLEXPORT void jl_array_grow_at(jl_array_t *a, ssize_t idx, size_t inc) { // No need to explicitly unshare. // Shared arrays are guaranteed to trigger the slow path for growing. size_t n = jl_array_nrows(a); if (idx < 0 || idx > n) jl_bounds_error_int((jl_value_t*)a, idx + 1); if (idx + 1 < n / 2) { jl_array_grow_at_beg(a, idx, inc, n); } else { jl_array_grow_at_end(a, idx, inc, n); } }
static void NOINLINE array_try_unshare(jl_array_t *a) { if (a->flags.isshared) { if (a->flags.how != 3) jl_error("cannot resize array with shared data"); assert(a->offset == 0); size_t len = jl_array_nrows(a); size_t es = a->elsize; size_t nbytes = len * es; char *olddata = (char*)a->data; int newbuf = array_resize_buffer(a, len); assert(newbuf); (void)newbuf; memcpy(a->data, olddata, nbytes); } }
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; array_resize_buffer(a, newlen, alen, a->offset); } #ifdef STORE_ARRAY_LEN a->length += inc; #endif a->nrows += inc; }
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); } }
JL_DLLEXPORT void jl_array_grow_beg(jl_array_t *a, size_t inc) { size_t n = jl_array_nrows(a); jl_array_grow_at_beg(a, 0, inc, n); }
JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc) { size_t n = jl_array_nrows(a); jl_array_grow_at_end(a, n, inc, n); }