home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / mysys / array.c next >
C/C++ Source or Header  |  2000-08-31  |  5KB  |  178 lines

  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.  
  18. /* Handling of arrays that can grow dynamicly. */
  19.  
  20. #if defined(WIN32) || defined(__WIN__)
  21. #undef SAFEMALLOC                /* Problems with threads */
  22. #endif
  23.  
  24. #include "mysys_priv.h"
  25. #include "m_string.h"
  26.  
  27. /*
  28.   Initiate array and alloc space for init_alloc elements. Array is usable
  29.   even if space allocation failed
  30. */
  31.  
  32. my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
  33.                uint init_alloc, uint alloc_increment)
  34. {
  35.   DBUG_ENTER("init_dynamic_array");
  36.   if (!alloc_increment)
  37.   { 
  38.     alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
  39.     if (init_alloc > 8 && alloc_increment > init_alloc * 2)
  40.       alloc_increment=init_alloc*2;
  41.   }
  42.  
  43.   if (!init_alloc)
  44.     init_alloc=alloc_increment;
  45.   array->elements=0;
  46.   array->max_element=init_alloc;
  47.   array->alloc_increment=alloc_increment;
  48.   array->size_of_element=element_size;
  49.   if (!(array->buffer=(char*) my_malloc(element_size*init_alloc,MYF(MY_WME))))
  50.   {
  51.     array->max_element=0;
  52.     DBUG_RETURN(TRUE);
  53.   }
  54.   DBUG_RETURN(FALSE);
  55. }
  56.  
  57.  
  58. my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
  59. {
  60.   gptr buffer;
  61.   if (array->elements == array->max_element)
  62.   {                        /* Call only when nessesary */
  63.     if (!(buffer=alloc_dynamic(array)))
  64.       return TRUE;
  65.   }
  66.   else
  67.   {
  68.     buffer=array->buffer+(array->elements * array->size_of_element);
  69.     array->elements++;
  70.   }
  71.   memcpy(buffer,element,(size_t) array->size_of_element);
  72.   return FALSE;
  73. }
  74.  
  75.  
  76.     /* Alloc room for one element */
  77.  
  78. byte *alloc_dynamic(DYNAMIC_ARRAY *array)
  79. {
  80.   if (array->elements == array->max_element)
  81.   {
  82.     char *new_ptr;
  83.     if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
  84.                      array->alloc_increment)*
  85.                      array->size_of_element,
  86.                      MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
  87.       return 0;
  88.     array->buffer=new_ptr;
  89.     array->max_element+=array->alloc_increment;
  90.   }
  91.   return array->buffer+(array->elements++ * array->size_of_element);
  92. }
  93.  
  94.  
  95.     /* remove last element from array and return it */
  96.  
  97. byte *pop_dynamic(DYNAMIC_ARRAY *array)
  98. {
  99.   if (array->elements)
  100.     return array->buffer+(--array->elements * array->size_of_element);
  101.   return 0;
  102. }
  103.  
  104.  
  105. my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
  106. {
  107.   if (idx >= array->elements)
  108.   {
  109.     if (idx >= array->max_element)
  110.     {
  111.       uint size;
  112.       char *new_ptr;
  113.       size=(idx+array->alloc_increment)/array->alloc_increment;
  114.       size*= array->alloc_increment;
  115.       if (!(new_ptr=(char*) my_realloc(array->buffer,size*
  116.                        array->size_of_element,
  117.                        MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
  118.     return TRUE;
  119.       array->buffer=new_ptr;
  120.       array->max_element=size;
  121.     }
  122.     bzero((gptr) (array->buffer+array->elements*array->size_of_element),
  123.       (idx - array->elements)*array->size_of_element);
  124.     array->elements=idx+1;
  125.   }
  126.   memcpy(array->buffer+(idx * array->size_of_element),element,
  127.      (size_t) array->size_of_element);
  128.   return FALSE;
  129. }
  130.  
  131.  
  132. void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
  133. {
  134.   if (idx >= array->elements)
  135.   {
  136.     DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
  137.               idx,array->elements));
  138.     bzero(element,array->size_of_element);
  139.     return;
  140.   }
  141.   memcpy(element,array->buffer+idx*array->size_of_element,
  142.      (size_t) array->size_of_element);
  143. }
  144.  
  145.  
  146. void delete_dynamic(DYNAMIC_ARRAY *array)
  147. {
  148.   if (array->buffer)
  149.   {
  150.     my_free(array->buffer,MYF(MY_WME));
  151.     array->buffer=0;
  152.     array->elements=array->max_element=0;
  153.   }
  154. }
  155.  
  156.  
  157. void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
  158. {
  159.   char *ptr=array->buffer+array->size_of_element*idx;
  160.   array->elements--;
  161.   memmove(ptr,ptr+array->size_of_element,
  162.       (array->elements-idx)*array->size_of_element);
  163. }
  164.  
  165.  
  166. void freeze_size(DYNAMIC_ARRAY *array)
  167. {
  168.   uint elements=max(array->elements,1);
  169.  
  170.   if (array->buffer && array->max_element != elements)
  171.   {
  172.     array->buffer=(char*) my_realloc(array->buffer,
  173.                      elements*array->size_of_element,
  174.                      MYF(MY_WME));
  175.     array->max_element=elements;
  176.   }
  177. }
  178.