void jl_array_grow_beg(jl_array_t *a, size_t inc) { // designed to handle the case of growing and shrinking at both ends if (inc == 0) return; size_t es = a->elsize; size_t nb = inc*es; if (a->offset >= inc) { a->data = (char*)a->data - nb; a->offset -= inc; } else { size_t alen = a->length; size_t anb = alen*es; char *newdata; if (inc > (a->maxsize-alen)/2 - (a->maxsize-alen)/20) { size_t newlen = a->maxsize==0 ? 2*inc : a->maxsize*2; while (alen+2*inc > newlen-a->offset) newlen *= 2; newdata = array_new_buffer(a, newlen); size_t center = (newlen - (alen + inc))/2; newdata += (center*es); a->maxsize = newlen; a->offset = center; } else { size_t center = (a->maxsize - (alen + inc))/2; newdata = (char*)a->data - es*a->offset + es*center; a->offset = center; } memmove(&newdata[nb], a->data, anb); a->data = newdata; } a->length += inc; a->nrows += inc; }
void jl_array_grow_end(jl_array_t *a, size_t inc) { // optimized for the case of only growing and shrinking at the end size_t alen = a->length; 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; char *newdata = array_new_buffer(a, newlen); size_t es = a->elsize; newdata += (a->offset*es); size_t anb = alen*es; memcpy(newdata, (char*)a->data, anb); if (es == 1) { memset(newdata + anb, 0, (newlen-a->offset-alen)*es); } a->maxsize = newlen; a->data = newdata; } a->length += inc; a->nrows += inc; }
jl_array_t *jl_reshape_array(jl_type_t *atype, jl_array_t *data, jl_tuple_t *dims) { size_t i; jl_array_t *a; size_t ndims = jl_tuple_len(dims); int ndimwords = jl_array_ndimwords(ndims); a = allocobj((sizeof(jl_array_t) + ndimwords*sizeof(size_t) + 15)&-16); a->type = atype; a->ndims = ndims; a->data = NULL; JL_GC_PUSH(&a); char *d = data->data; if (data->ndims == 1) d -= data->offset*data->elsize; if (d == jl_array_inline_data_area(data)) { if (data->ndims == 1) { // data might resize, so switch it to shared representation. // problem: we'd like to do that, but it might not be valid, // since the buffer might be used from C in a way that it's // assumed not to move. for now, just copy the data (note this // case only happens for sizes <= ARRAY_INLINE_NBYTES) jl_mallocptr_t *mp = array_new_buffer(data, data->length); memcpy(mp->ptr, data->data, data->length * data->elsize); a->data = mp->ptr; jl_array_data_owner(a) = (jl_value_t*)mp; a->ismalloc = 1; //data->data = mp->ptr; //data->offset = 0; //data->maxsize = data->length; //jl_array_data_owner(data) = (jl_value_t*)mp; } else { a->ismalloc = 0; jl_array_data_owner(a) = (jl_value_t*)data; } } else { a->ismalloc = data->ismalloc; jl_array_data_owner(a) = jl_array_data_owner(data); } if (a->data == NULL) a->data = data->data; jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype); if (jl_is_bits_type(el_type)) { a->elsize = jl_bitstype_nbits(el_type)/8; a->ptrarray = 0; } else { a->elsize = sizeof(void*); a->ptrarray = 1; } if (ndims == 1) { a->length = jl_unbox_long(jl_tupleref(dims,0)); a->nrows = a->length; a->maxsize = a->length; a->offset = 0; } else { size_t *adims = &a->nrows; size_t l=1; for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_tupleref(dims, i)); l *= adims[i]; } a->length = l; } JL_GC_POP(); return a; }