diff options
author | unknown <sasha@mysql.sashanet.com> | 2001-05-12 19:50:51 -0600 |
---|---|---|
committer | unknown <sasha@mysql.sashanet.com> | 2001-05-12 19:50:51 -0600 |
commit | b7b7eb9c05f3036da3f90b5cad03a3b47d1f7aa2 (patch) | |
tree | 9a5be3c1de61f22213e62a51418e4cb6820cdc33 /mysys/my_alloc.c | |
parent | 64984296241873f90e39d744b59690c7b3b408bb (diff) | |
download | mariadb-git-b7b7eb9c05f3036da3f90b5cad03a3b47d1f7aa2.tar.gz |
option to free_root() to not my_free() the blocks
fixed bug/updated count_distinct2 test
changed reset in count distinct to avoid calls to my_free()
include/my_sys.h:
option to free_root() not to do my_free()
include/my_tree.h:
reset_tree()
mysql-test/r/count_distinct2.result:
added group by test
mysql-test/t/count_distinct2.test:
group by test + fixed bug - need to drop table
mysys/my_alloc.c:
mark_blocks_free()
mysys/tree.c:
reset_tree()
sql/item_sum.cc:
in count distinct reset_tree instead of delete_tree
Diffstat (limited to 'mysys/my_alloc.c')
-rw-r--r-- | mysys/my_alloc.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index db482454e69..b82ff965dfb 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -100,7 +100,41 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) #endif } - /* deallocate everything used by alloc_root */ +static inline void mark_blocks_free(MEM_ROOT* root) +{ + reg1 USED_MEM *next,*last = 0; + + /* iterate through (partially) free blocks, mark them fully free */ + for(next = root->free; next; next = next->next ) + { + last = next; + next->left = next->size - ALIGN_SIZE(sizeof(USED_MEM)); + } + /* if free block list was not empty, point the next of the + last free block to the beginning of the used list */ + next = root->used; /* a little optimization to avoid dereferencing root + twice - we will shortly start iterating through used + list */ + if(last) + last->next = next; + else /* if free list is empty, just point it to the current used*/ + root->free = next; + + /* now go through the current used list, and mark each block + as fully free. Note that because of our optimization, we do not + need to initialize next here - see above + */ + for(;next; next = next->next) + next->left = next->size - ALIGN_SIZE(sizeof(USED_MEM)); + + /* Now everything is set - we just need to indicate that nothing is used + anymore + */ + root->used = 0; +} + + /* deallocate everything used by alloc_root or just move + used blocks to free list if called with MY_USED_TO_FREE */ void free_root(MEM_ROOT *root, myf MyFlags) { @@ -109,6 +143,11 @@ void free_root(MEM_ROOT *root, myf MyFlags) if (!root) DBUG_VOID_RETURN; /* purecov: inspected */ + if(MyFlags & MY_MARK_BLOCKS_FREE) + { + mark_blocks_free(root); + DBUG_VOID_RETURN; + } if (!(MyFlags & MY_KEEP_PREALLOC)) root->pre_alloc=0; |