diff options
Diffstat (limited to 'mysys/array.c')
-rw-r--r-- | mysys/array.c | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/mysys/array.c b/mysys/array.c index 60f5b255e18..8a539f18a20 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -22,9 +22,10 @@ Initiate dynamic array SYNOPSIS - init_dynamic_array() + init_dynamic_array2() array Pointer to an array element_size Size of element + init_buffer Initial buffer pointer init_alloc Number of initial elements alloc_increment Increment for adding new elements @@ -32,15 +33,16 @@ init_dynamic_array() initiates array and allocate space for init_alloc eilements. Array is usable even if space allocation failed. + Static buffers must begin immediately after the array structure. RETURN VALUE TRUE my_malloc_ci() failed FALSE Ok */ -my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, - uint alloc_increment CALLER_INFO_PROTO) +my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, + void *init_buffer, uint init_alloc, + uint alloc_increment CALLER_INFO_PROTO) { DBUG_ENTER("init_dynamic_array"); if (!alloc_increment) @@ -51,12 +53,17 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, } if (!init_alloc) + { init_alloc=alloc_increment; + init_buffer= 0; + } array->elements=0; array->max_element=init_alloc; array->alloc_increment=alloc_increment; array->size_of_element=element_size; - if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME)))) + if ((array->buffer= init_buffer)) + DBUG_RETURN(FALSE); + if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME)))) { array->max_element=0; DBUG_RETURN(TRUE); @@ -64,6 +71,14 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, DBUG_RETURN(FALSE); } +my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, + uint init_alloc, + uint alloc_increment CALLER_INFO_PROTO) +{ + /* placeholder to preserve ABI */ + return my_init_dynamic_array_ci(array, element_size, init_alloc, + alloc_increment); +} /* Insert element at the end of array. Allocate memory if needed. @@ -77,9 +92,9 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, FALSE Ok */ -my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element) +my_bool insert_dynamic(DYNAMIC_ARRAY *array, uchar* element) { - gptr buffer; + uchar* buffer; if (array->elements == array->max_element) { /* Call only when nessesary */ if (!(buffer=alloc_dynamic(array))) @@ -112,17 +127,32 @@ my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element) 0 Error */ -byte *alloc_dynamic(DYNAMIC_ARRAY *array) +uchar *alloc_dynamic(DYNAMIC_ARRAY *array) { if (array->elements == array->max_element) { char *new_ptr; + if (array->buffer == (uchar *)(array + 1)) + { + /* + In this senerio, the buffer is statically preallocated, + so we have to create an all-new malloc since we overflowed + */ + if (!(new_ptr= (char *) my_malloc((array->max_element+ + array->alloc_increment) * + array->size_of_element, + MYF(MY_WME)))) + return 0; + memcpy(new_ptr, array->buffer, + array->elements * array->size_of_element); + } + else if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+ - array->alloc_increment)* - array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + array->alloc_increment)* + array->size_of_element, + MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) return 0; - array->buffer=new_ptr; + array->buffer= (uchar*) new_ptr; array->max_element+=array->alloc_increment; } return array->buffer+(array->elements++ * array->size_of_element); @@ -141,7 +171,7 @@ byte *alloc_dynamic(DYNAMIC_ARRAY *array) 0 Array is empty */ -byte *pop_dynamic(DYNAMIC_ARRAY *array) +uchar *pop_dynamic(DYNAMIC_ARRAY *array) { if (array->elements) return array->buffer+(--array->elements * array->size_of_element); @@ -166,7 +196,7 @@ byte *pop_dynamic(DYNAMIC_ARRAY *array) FALSE Ok */ -my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) +my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) { if (idx >= array->elements) { @@ -176,19 +206,33 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) char *new_ptr; size=(idx+array->alloc_increment)/array->alloc_increment; size*= array->alloc_increment; + if (array->buffer == (uchar *)(array + 1)) + { + /* + In this senerio, the buffer is statically preallocated, + so we have to create an all-new malloc since we overflowed + */ + if (!(new_ptr= (char *) my_malloc(size * + array->size_of_element, + MYF(MY_WME)))) + return 0; + memcpy(new_ptr, array->buffer, + array->elements * array->size_of_element); + } + else if (!(new_ptr=(char*) my_realloc(array->buffer,size* - array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + array->size_of_element, + MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) return TRUE; - array->buffer=new_ptr; + array->buffer= (uchar*) new_ptr; array->max_element=size; } - bzero((gptr) (array->buffer+array->elements*array->size_of_element), - (idx - array->elements)*array->size_of_element); + bzero((uchar*) (array->buffer+array->elements*array->size_of_element), + (idx - array->elements)*array->size_of_element); array->elements=idx+1; } memcpy(array->buffer+(idx * array->size_of_element),element, - (size_t) array->size_of_element); + (size_t) array->size_of_element); return FALSE; } @@ -198,21 +242,21 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) SYNOPSIS get_dynamic() array - gptr Element to be returned. If idx > elements contain zeroes. + uchar* Element to be returned. If idx > elements contain zeroes. idx Index of element wanted. */ -void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) +void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) { if (idx >= array->elements) { DBUG_PRINT("warning",("To big array idx: %d, array size is %d", - idx,array->elements)); + idx,array->elements)); bzero(element,array->size_of_element); return; } memcpy(element,array->buffer+idx*array->size_of_element, - (size_t) array->size_of_element); + (size_t) array->size_of_element); } @@ -226,6 +270,12 @@ void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) void delete_dynamic(DYNAMIC_ARRAY *array) { + /* + Just mark as empty if we are using a static buffer + */ + if (array->buffer == (uchar *)(array + 1)) + array->elements= 0; + else if (array->buffer) { my_free(array->buffer,MYF(MY_WME)); @@ -240,15 +290,15 @@ void delete_dynamic(DYNAMIC_ARRAY *array) SYNOPSIS delete_dynamic_element() array - idx Index of element to be deleted + idx Index of element to be deleted */ void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx) { - char *ptr=array->buffer+array->size_of_element*idx; + char *ptr= (char*) array->buffer+array->size_of_element*idx; array->elements--; memmove(ptr,ptr+array->size_of_element, - (array->elements-idx)*array->size_of_element); + (array->elements-idx)*array->size_of_element); } @@ -265,11 +315,17 @@ void freeze_size(DYNAMIC_ARRAY *array) { uint elements=max(array->elements,1); + /* + Do nothing if we are using a static buffer + */ + if (array->buffer == (uchar *)(array + 1)) + return; + if (array->buffer && array->max_element != elements) { - array->buffer=(char*) my_realloc(array->buffer, - elements*array->size_of_element, - MYF(MY_WME)); + array->buffer=(uchar*) my_realloc(array->buffer, + elements*array->size_of_element, + MYF(MY_WME)); array->max_element=elements; } } @@ -285,7 +341,7 @@ void freeze_size(DYNAMIC_ARRAY *array) */ -int get_index_dynamic(DYNAMIC_ARRAY *array, gptr element) +int get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element) { uint ret; if (array->buffer > element) |