From b7b7eb9c05f3036da3f90b5cad03a3b47d1f7aa2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 12 May 2001 19:50:51 -0600 Subject: 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 --- mysys/my_alloc.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'mysys/my_alloc.c') 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; -- cgit v1.2.1