diff options
| author | Aleksey Midenkov <midenok@gmail.com> | 2020-11-05 05:52:20 +0300 |
|---|---|---|
| committer | Aleksey Midenkov <midenok@gmail.com> | 2021-04-23 12:17:53 +0300 |
| commit | 7946754f2c6265d69d0cc59afb11db3fe60b7e88 (patch) | |
| tree | c7e15f60d7545c8fc305b2dc98e88ee1251ed549 | |
| parent | 40fec7c81600b20bd3fc0487cd77a18feca6f286 (diff) | |
| download | mariadb-git-bb-10.2-midenok-MDEV-18734.tar.gz | |
MDEV-18734 malloc optimization for m_ordered_rootbb-10.2-midenok-MDEV-18734
- Does 1 malloc when allocating from m_ordered_root;
- init_prealloc_root() interface with user-friendly
block_size/prealloc_size parameters.
| -rw-r--r-- | include/my_sys.h | 2 | ||||
| -rw-r--r-- | mysys/my_alloc.c | 19 | ||||
| -rw-r--r-- | sql/ha_partition.cc | 27 |
3 files changed, 44 insertions, 4 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index ac1730eeaff..6a4a321162f 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -900,6 +900,8 @@ extern void my_free_lock(void *ptr); #define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; (A)->min_malloc=0;} while(0) extern void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, size_t pre_alloc_size, myf my_flags); +extern void init_prealloc_root(MEM_ROOT *mem_root, size_t block_size, + size_t prealloc_size, myf my_flags); extern void *alloc_root(MEM_ROOT *mem_root, size_t Size); extern void *multi_alloc_root(MEM_ROOT *mem_root, ...); extern void free_root(MEM_ROOT *root, myf MyFLAGS); diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index d67b8be9bb8..a20f2969c46 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -89,6 +89,25 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, DBUG_VOID_RETURN; } +void init_prealloc_root(MEM_ROOT *mem_root, size_t block_size, + size_t prealloc_size, myf my_flags) +{ + size_t pre_alloc; + init_alloc_root(mem_root, block_size + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, my_flags); + if (!prealloc_size) + return; + pre_alloc= prealloc_size + (prealloc_size / block_size + 1) * ALLOC_ROOT_MIN_BLOCK_SIZE; + if ((mem_root->free= mem_root->pre_alloc= + (USED_MEM*) my_malloc(pre_alloc + ALIGN_SIZE(sizeof(USED_MEM)), + MYF(my_flags)))) + { + mem_root->free->size= pre_alloc + ALIGN_SIZE(sizeof(USED_MEM)); + mem_root->free->left= pre_alloc; + mem_root->free->next= 0; + TRASH_MEM(mem_root->free); + } +} + /* SYNOPSIS reset_root_defaults() diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index cdd17efaa20..fe9c0033262 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5132,7 +5132,20 @@ bool ha_partition::init_record_priority_queue() /* Allocate a key for temporary use when setting up the scan. */ alloc_len+= table_share->max_key_length; - init_alloc_root(&m_ordered_root, 512, 0, MYF(MY_WME)); + size_t storage_size; + if (table->s->blob_fields) + { + size_t block_size, prealloc_size; + storage_size= table->s->blob_fields * sizeof(Ordered_blob_storage *); + block_size= storage_size < sizeof(Ordered_blob_storage) ? + storage_size : sizeof(Ordered_blob_storage); + prealloc_size= alloc_len + used_parts * (storage_size + + table->s->blob_fields * sizeof(Ordered_blob_storage)); + DBUG_ASSERT(block_size > 0); + init_prealloc_root(&m_ordered_root, block_size, prealloc_size, MYF(MY_WME)); + } + else + init_prealloc_root(&m_ordered_root, alloc_len, 0, MYF(MY_WME)); if (!(m_ordered_rec_buffer= (uchar*) alloc_root(&m_ordered_root, alloc_len))) DBUG_RETURN(true); @@ -5154,9 +5167,15 @@ bool ha_partition::init_record_priority_queue() if (table->s->blob_fields) { Ordered_blob_storage **blob_storage= (Ordered_blob_storage **) - alloc_root(&m_ordered_root, table->s->blob_fields * sizeof(Ordered_blob_storage *)); - for (uint i= 0; i < table->s->blob_fields; ++i) - blob_storage[i]= new (&m_ordered_root) Ordered_blob_storage; + alloc_root(&m_ordered_root, storage_size); + if (!blob_storage) + DBUG_RETURN(true); + for (uint j= 0; j < table->s->blob_fields; ++j) + { + blob_storage[j]= new (&m_ordered_root) Ordered_blob_storage; + if (!blob_storage[j]) + DBUG_RETURN(true); + } *((Ordered_blob_storage ***) ptr)= blob_storage; } int2store(ptr + sizeof(String **), i); |
