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
This commit is contained in:
Sergey Vojtovich 2014-12-04 17:35:55 +04:00
parent 974808772b
commit 9127784d5c
4 changed files with 42 additions and 26 deletions

View File

@ -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 */

View File

@ -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,
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)
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)
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)
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,6 +247,7 @@ 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,
@ -293,16 +298,12 @@ 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->buffer= 0;
array->elements= array->max_element= 0; array->elements= array->max_element= 0;
} }
}
/* /*
Delete element by given index Delete element by given index
@ -350,15 +351,16 @@ 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,
@ -367,7 +369,7 @@ void freeze_size(DYNAMIC_ARRAY *array)
} }
} }
#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)
return ret; return ret;
} }
#endif

View File

@ -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)
#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,7 +189,7 @@ 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
@ -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)
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)
{ {
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)
{ {

View File

@ -105,6 +105,13 @@ public:
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,