Commit 9127784d authored by Sergey Vojtovich's avatar Sergey Vojtovich

Cherry pick dynamic array changes from commit:

commit 85fd3d901311688e18ffce92ffc78129e5625791
Author: Monty <monty@mariadb.org>
Date:   Fri Aug 29 14:07:43 2014 +0300

    my_alloc.c
    - Changed 0x%lx -> %p
    array.c:
    - Static (preallocated) buffer can now be anywhere
    my_sys.h
    - Define MY_INIT_BUFFER_USED
    sql_delete.cc & sql_lex.cc
    - Use memroot when allocating classes (avoids call to current_thd)
    sql_explain.h:
    - Use preallocated buffers
    sql_explain.cc:
    - Use preallocated buffers and memroot
    sql_select.cc:
    - Use multi_alloc_root() instead of many alloc_root()
    - Update calls to Explain
parent 97480877
...@@ -78,6 +78,11 @@ typedef struct my_aio_result { ...@@ -78,6 +78,11 @@ typedef struct my_aio_result {
#define MY_SHORT_WAIT 64 /* my_lock() don't wait if can't lock */ #define MY_SHORT_WAIT 64 /* my_lock() don't wait if can't lock */
#define MY_FORCE_LOCK 128 /* use my_lock() even if disable_locking */ #define MY_FORCE_LOCK 128 /* use my_lock() even if disable_locking */
#define MY_NO_WAIT 256 /* my_lock() don't wait at all */ #define MY_NO_WAIT 256 /* my_lock() don't wait at all */
/*
init_dynamic_array() has init buffer; Internal flag, not to be used by
caller.
*/
#define MY_INIT_BUFFER_USED 256
#define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */ #define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */
#define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */ #define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */
#define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */ #define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
init_alloc eilements. init_alloc eilements.
Array is usable even if space allocation failed, hence, the Array is usable even if space allocation failed, hence, the
function never returns TRUE. function never returns TRUE.
Static buffers must begin immediately after the array structure.
RETURN VALUE RETURN VALUE
FALSE Ok FALSE Ok
...@@ -57,8 +56,12 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, ...@@ -57,8 +56,12 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
array->alloc_increment=alloc_increment; array->alloc_increment=alloc_increment;
array->size_of_element=element_size; array->size_of_element=element_size;
array->malloc_flags= my_flags; array->malloc_flags= my_flags;
DBUG_ASSERT((my_flags & MY_INIT_BUFFER_USED) == 0);
if ((array->buffer= init_buffer)) if ((array->buffer= init_buffer))
{
array->malloc_flags|= MY_INIT_BUFFER_USED;
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
}
/* /*
Since the dynamic array is usable even if allocation fails here malloc Since the dynamic array is usable even if allocation fails here malloc
should not throw an error should not throw an error
...@@ -124,10 +127,10 @@ void *alloc_dynamic(DYNAMIC_ARRAY *array) ...@@ -124,10 +127,10 @@ void *alloc_dynamic(DYNAMIC_ARRAY *array)
if (array->elements == array->max_element) if (array->elements == array->max_element)
{ {
char *new_ptr; char *new_ptr;
if (array->buffer == (uchar *)(array + 1)) if (array->malloc_flags & MY_INIT_BUFFER_USED)
{ {
/* /*
In this senerio, the buffer is statically preallocated, In this scenario, the buffer is statically preallocated,
so we have to create an all-new malloc since we overflowed so we have to create an all-new malloc since we overflowed
*/ */
if (!(new_ptr= (char *) my_malloc((array->max_element+ if (!(new_ptr= (char *) my_malloc((array->max_element+
...@@ -137,6 +140,7 @@ void *alloc_dynamic(DYNAMIC_ARRAY *array) ...@@ -137,6 +140,7 @@ void *alloc_dynamic(DYNAMIC_ARRAY *array)
DBUG_RETURN(0); DBUG_RETURN(0);
memcpy(new_ptr, array->buffer, memcpy(new_ptr, array->buffer,
array->elements * array->size_of_element); array->elements * array->size_of_element);
array->malloc_flags&= ~MY_INIT_BUFFER_USED;
} }
else if (!(new_ptr=(char*) else if (!(new_ptr=(char*)
my_realloc(array->buffer,(array->max_element+ my_realloc(array->buffer,(array->max_element+
...@@ -231,7 +235,7 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) ...@@ -231,7 +235,7 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
uchar *new_ptr; uchar *new_ptr;
size= (max_elements + array->alloc_increment)/array->alloc_increment; size= (max_elements + array->alloc_increment)/array->alloc_increment;
size*= array->alloc_increment; size*= array->alloc_increment;
if (array->buffer == (uchar *)(array + 1)) if (array->malloc_flags & MY_INIT_BUFFER_USED)
{ {
/* /*
In this senerio, the buffer is statically preallocated, In this senerio, the buffer is statically preallocated,
...@@ -243,7 +247,8 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) ...@@ -243,7 +247,8 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
DBUG_RETURN(0); DBUG_RETURN(0);
memcpy(new_ptr, array->buffer, memcpy(new_ptr, array->buffer,
array->elements * array->size_of_element); array->elements * array->size_of_element);
} array->malloc_flags&= ~MY_INIT_BUFFER_USED;
}
else if (!(new_ptr= (uchar*) my_realloc(array->buffer,size* else if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
array->size_of_element, array->size_of_element,
MYF(MY_WME | MY_ALLOW_ZERO_PTR | MYF(MY_WME | MY_ALLOW_ZERO_PTR |
...@@ -293,15 +298,11 @@ void delete_dynamic(DYNAMIC_ARRAY *array) ...@@ -293,15 +298,11 @@ void delete_dynamic(DYNAMIC_ARRAY *array)
/* /*
Just mark as empty if we are using a static buffer Just mark as empty if we are using a static buffer
*/ */
if (array->buffer == (uchar *)(array + 1)) if (!(array->malloc_flags & MY_INIT_BUFFER_USED) && array->buffer)
array->elements= 0;
else
if (array->buffer)
{
my_free(array->buffer); my_free(array->buffer);
array->buffer=0;
array->elements=array->max_element=0; array->buffer= 0;
} array->elements= array->max_element= 0;
} }
/* /*
...@@ -350,24 +351,25 @@ void delete_dynamic_with_callback(DYNAMIC_ARRAY *array, FREE_FUNC f) { ...@@ -350,24 +351,25 @@ void delete_dynamic_with_callback(DYNAMIC_ARRAY *array, FREE_FUNC f) {
void freeze_size(DYNAMIC_ARRAY *array) void freeze_size(DYNAMIC_ARRAY *array)
{ {
uint elements=MY_MAX(array->elements,1); uint elements;
/* /*
Do nothing if we are using a static buffer Do nothing if we are using a static buffer
*/ */
if (array->buffer == (uchar *)(array + 1)) if (array->malloc_flags & MY_INIT_BUFFER_USED)
return; return;
if (array->buffer && array->max_element != elements) elements= MY_MAX(array->elements, 1);
if (array->buffer && array->max_element > elements)
{ {
array->buffer=(uchar*) my_realloc(array->buffer, array->buffer=(uchar*) my_realloc(array->buffer,
elements*array->size_of_element, elements*array->size_of_element,
MYF(MY_WME | array->malloc_flags)); MYF(MY_WME | array->malloc_flags));
array->max_element=elements; array->max_element= elements;
} }
} }
#ifdef NOT_USED
/* /*
Get the index of a dynamic element Get the index of a dynamic element
...@@ -391,3 +393,4 @@ int get_index_dynamic(DYNAMIC_ARRAY *array, void* element) ...@@ -391,3 +393,4 @@ int get_index_dynamic(DYNAMIC_ARRAY *array, void* element)
return ret; return ret;
} }
#endif
...@@ -56,7 +56,8 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, ...@@ -56,7 +56,8 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
myf my_flags) myf my_flags)
{ {
DBUG_ENTER("init_alloc_root"); DBUG_ENTER("init_alloc_root");
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); DBUG_PRINT("enter",("root: %p prealloc: %zu", mem_root,
pre_alloc_size));
mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
mem_root->min_malloc= 32; mem_root->min_malloc= 32;
...@@ -164,7 +165,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) ...@@ -164,7 +165,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
#if defined(HAVE_valgrind) && defined(EXTRA_DEBUG) #if defined(HAVE_valgrind) && defined(EXTRA_DEBUG)
reg1 USED_MEM *next; reg1 USED_MEM *next;
DBUG_ENTER("alloc_root"); DBUG_ENTER("alloc_root");
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); DBUG_PRINT("enter",("root: %p", mem_root));
DBUG_ASSERT(alloc_root_inited(mem_root)); DBUG_ASSERT(alloc_root_inited(mem_root));
...@@ -188,8 +189,8 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) ...@@ -188,8 +189,8 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
next->next= mem_root->used; next->next= mem_root->used;
next->size= length; next->size= length;
mem_root->used= next; mem_root->used= next;
DBUG_PRINT("exit",("ptr: 0x%lx", (long) (((char*) next)+ DBUG_PRINT("exit",("ptr: %p", (((char*) next)+
ALIGN_SIZE(sizeof(USED_MEM))))); ALIGN_SIZE(sizeof(USED_MEM)))));
DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)))); DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
#else #else
size_t get_size, block_size; size_t get_size, block_size;
...@@ -197,7 +198,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) ...@@ -197,7 +198,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
reg1 USED_MEM *next= 0; reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev; reg2 USED_MEM **prev;
DBUG_ENTER("alloc_root"); DBUG_ENTER("alloc_root");
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); DBUG_PRINT("enter",("root: %p", mem_root));
DBUG_ASSERT(alloc_root_inited(mem_root)); DBUG_ASSERT(alloc_root_inited(mem_root));
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_EXECUTE_IF("simulate_out_of_memory",
...@@ -256,7 +257,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) ...@@ -256,7 +257,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
mem_root->first_block_usage= 0; mem_root->first_block_usage= 0;
} }
TRASH_ALLOC(point, length); TRASH_ALLOC(point, length);
DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point)); DBUG_PRINT("exit",("ptr: %p", point));
DBUG_RETURN((void*) point); DBUG_RETURN((void*) point);
#endif #endif
} }
...@@ -368,7 +369,7 @@ void free_root(MEM_ROOT *root, myf MyFlags) ...@@ -368,7 +369,7 @@ void free_root(MEM_ROOT *root, myf MyFlags)
{ {
reg1 USED_MEM *next,*old; reg1 USED_MEM *next,*old;
DBUG_ENTER("free_root"); DBUG_ENTER("free_root");
DBUG_PRINT("enter",("root: 0x%lx flags: %u", (long) root, (uint) MyFlags)); DBUG_PRINT("enter",("root: %p flags: %u", root, (uint) MyFlags));
if (MyFlags & MY_MARK_BLOCKS_FREE) if (MyFlags & MY_MARK_BLOCKS_FREE)
{ {
......
...@@ -105,6 +105,13 @@ template <class Elem> class Dynamic_array ...@@ -105,6 +105,13 @@ template <class Elem> class Dynamic_array
init(prealloc, increment); init(prealloc, increment);
} }
Dynamic_array(MEM_ROOT *root, uint prealloc=16, uint increment=16)
{
void *init_buffer= alloc_root(root, sizeof(Elem) * prealloc);
my_init_dynamic_array2(&array, sizeof(Elem), init_buffer,
prealloc, increment, MYF(0));
}
void init(uint prealloc=16, uint increment=16) void init(uint prealloc=16, uint increment=16)
{ {
my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment, my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment