summaryrefslogtreecommitdiff
path: root/mysys/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/array.c')
-rw-r--r--mysys/array.c118
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)