my_alloc.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This library is free software; you can redistribute it and/or
  4.    modify it under the terms of the GNU Library General Public
  5.    License as published by the Free Software Foundation; either
  6.    version 2 of the License, or (at your option) any later version.
  7.    
  8.    This library is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.    Library General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU Library General Public
  14.    License along with this library; if not, write to the Free
  15.    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  16.    MA 02111-1307, USA */
  17. /* Routines to handle mallocing of results which will be freed the same time */
  18. #include <global.h>
  19. #include <my_sys.h>
  20. #include <m_string.h>
  21. void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size)
  22. {
  23.   mem_root->free=mem_root->used=0;
  24.   mem_root->min_malloc=16;
  25.   mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
  26.   mem_root->error_handler=0;
  27. #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
  28.   if (pre_alloc_size)
  29.   {
  30.     if ((mem_root->free = mem_root->pre_alloc=
  31.  (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
  32.        MYF(0))))
  33.     {
  34.       mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
  35.       mem_root->free->left=pre_alloc_size;
  36.       mem_root->free->next=0;
  37.     }
  38.   }
  39. #endif
  40. }
  41. gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
  42. {
  43. #if defined(HAVE_purify) && defined(EXTRA_DEBUG)
  44.   reg1 USED_MEM *next;
  45.   Size+=ALIGN_SIZE(sizeof(USED_MEM));
  46.   if (!(next = (USED_MEM*) my_malloc(Size,MYF(MY_WME))))
  47.   {
  48.     if (mem_root->error_handler)
  49.       (*mem_root->error_handler)();
  50.     return((gptr) 0); /* purecov: inspected */
  51.   }
  52.   next->next=mem_root->used;
  53.   mem_root->used=next;
  54.   return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
  55. #else
  56.   uint get_size,max_left;
  57.   gptr point;
  58.   reg1 USED_MEM *next;
  59.   reg2 USED_MEM **prev;
  60.   Size= ALIGN_SIZE(Size);
  61.   prev= &mem_root->free;
  62.   max_left=0;
  63.   for (next= *prev ; next && next->left < Size ; next= next->next)
  64.   {
  65.     if (next->left > max_left)
  66.       max_left=next->left;
  67.     prev= &next->next;
  68.   }
  69.   if (! next)
  70.   { /* Time to alloc new block */
  71.     get_size= Size+ALIGN_SIZE(sizeof(USED_MEM));
  72.     if (max_left*4 < mem_root->block_size && get_size < mem_root->block_size)
  73.       get_size=mem_root->block_size; /* Normal alloc */
  74.     if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
  75.     {
  76.       if (mem_root->error_handler)
  77. (*mem_root->error_handler)();
  78.       return((gptr) 0); /* purecov: inspected */
  79.     }
  80.     next->next= *prev;
  81.     next->size= get_size;
  82.     next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
  83.     *prev=next;
  84.   }
  85.   point= (gptr) ((char*) next+ (next->size-next->left));
  86.   if ((next->left-= Size) < mem_root->min_malloc)
  87.   { /* Full block */
  88.     *prev=next->next; /* Remove block from list */
  89.     next->next=mem_root->used;
  90.     mem_root->used=next;
  91.   }
  92.   return(point);
  93. #endif
  94. }
  95. /* deallocate everything used by alloc_root */
  96. void free_root(MEM_ROOT *root, myf MyFlags)
  97. {
  98.   reg1 USED_MEM *next,*old;
  99.   DBUG_ENTER("free_root");
  100.   if (!root)
  101.     DBUG_VOID_RETURN; /* purecov: inspected */
  102.   if (!(MyFlags & MY_KEEP_PREALLOC))
  103.     root->pre_alloc=0;
  104.   for ( next=root->used; next ;)
  105.   {
  106.     old=next; next= next->next ;
  107.     if (old != root->pre_alloc)
  108.       my_free((gptr) old,MYF(0));
  109.   }
  110.   for (next= root->free ; next ; )
  111.   {
  112.     old=next; next= next->next ;
  113.     if (old != root->pre_alloc)
  114.       my_free((gptr) old,MYF(0));
  115.   }
  116.   root->used=root->free=0;
  117.   if (root->pre_alloc)
  118.   {
  119.     root->free=root->pre_alloc;
  120.     root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
  121.     root->free->next=0;
  122.   }
  123.   DBUG_VOID_RETURN;
  124. }
  125. char *strdup_root(MEM_ROOT *root,const char *str)
  126. {
  127.   uint len= (uint) strlen(str)+1;
  128.   char *pos;
  129.   if ((pos=alloc_root(root,len)))
  130.     memcpy(pos,str,len);
  131.   return pos;
  132. }
  133. char *memdup_root(MEM_ROOT *root,const char *str,uint len)
  134. {
  135.   char *pos;
  136.   if ((pos=alloc_root(root,len)))
  137.     memcpy(pos,str,len);
  138.   return pos;
  139. }