array.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* Handling of arrays that can grow dynamicly. */
  14. #if defined(WIN32) || defined(__WIN__)
  15. #undef SAFEMALLOC /* Problems with threads */
  16. #endif
  17. #include "mysys_priv.h"
  18. #include "m_string.h"
  19. /*
  20.   Initiate dynamic array
  21.   SYNOPSIS
  22.     init_dynamic_array()
  23.       array Pointer to an array
  24.       element_size Size of element
  25.       init_alloc Number of initial elements
  26.       alloc_increment Increment for adding new elements
  27.   DESCRIPTION
  28.     init_dynamic_array() initiates array and allocate space for 
  29.     init_alloc eilements. 
  30.     Array is usable even if space allocation failed.
  31.   RETURN VALUE
  32.     TRUE my_malloc_ci() failed
  33.     FALSE Ok
  34. */
  35. my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
  36.     uint init_alloc,
  37.     uint alloc_increment CALLER_INFO_PROTO)
  38. {
  39.   DBUG_ENTER("init_dynamic_array");
  40.   if (!alloc_increment)
  41.   {
  42.     alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
  43.     if (init_alloc > 8 && alloc_increment > init_alloc * 2)
  44.       alloc_increment=init_alloc*2;
  45.   }
  46.   if (!init_alloc)
  47.     init_alloc=alloc_increment;
  48.   array->elements=0;
  49.   array->max_element=init_alloc;
  50.   array->alloc_increment=alloc_increment;
  51.   array->size_of_element=element_size;
  52.   if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME))))
  53.   {
  54.     array->max_element=0;
  55.     DBUG_RETURN(TRUE);
  56.   }
  57.   DBUG_RETURN(FALSE);
  58. /*
  59.   Insert element at the end of array. Allocate memory if needed.
  60.   SYNOPSIS
  61.     insert_dynamic()
  62.       array
  63.       element
  64.   RETURN VALUE
  65.     TRUE Insert failed
  66.     FALSE Ok
  67. */
  68. my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
  69. {
  70.   gptr buffer;
  71.   if (array->elements == array->max_element)
  72.   { /* Call only when nessesary */
  73.     if (!(buffer=alloc_dynamic(array)))
  74.       return TRUE;
  75.   }
  76.   else
  77.   {
  78.     buffer=array->buffer+(array->elements * array->size_of_element);
  79.     array->elements++;
  80.   }
  81.   memcpy(buffer,element,(size_t) array->size_of_element);
  82.   return FALSE;
  83. }
  84. /*
  85.   Alloc space for next element(s) 
  86.   SYNOPSIS
  87.     alloc_dynamic()
  88.       array
  89.   DESCRIPTION
  90.     alloc_dynamic() checks if there is empty space for at least
  91.     one element if not tries to allocate space for alloc_increment
  92.     elements at the end of array.
  93.   RETURN VALUE
  94.     pointer Pointer to empty space for element
  95.     0 Error
  96. */
  97. byte *alloc_dynamic(DYNAMIC_ARRAY *array)
  98. {
  99.   if (array->elements == array->max_element)
  100.   {
  101.     char *new_ptr;
  102.     if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
  103.      array->alloc_increment)*
  104.      array->size_of_element,
  105.      MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
  106.       return 0;
  107.     array->buffer=new_ptr;
  108.     array->max_element+=array->alloc_increment;
  109.   }
  110.   return array->buffer+(array->elements++ * array->size_of_element);
  111. }
  112. /*
  113.   Pop last element from array.
  114.   SYNOPSIS
  115.     pop_dynamic()
  116.       array
  117.   
  118.   RETURN VALUE    
  119.     pointer Ok
  120.     0 Array is empty
  121. */
  122. byte *pop_dynamic(DYNAMIC_ARRAY *array)
  123. {
  124.   if (array->elements)
  125.     return array->buffer+(--array->elements * array->size_of_element);
  126.   return 0;
  127. }
  128. /*
  129.   Replace elemnent in array with given element and index
  130.   SYNOPSIS
  131.     set_dynamic()
  132.       array
  133.       element Element to be inserted
  134.       idx Index where element is to be inserted
  135.   DESCRIPTION
  136.     set_dynamic() replaces element in array. 
  137.     If idx > max_element insert new element. Allocate memory if needed. 
  138.  
  139.   RETURN VALUE
  140.     TRUE Idx was out of range and allocation of new memory failed
  141.     FALSE Ok
  142. */
  143. my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
  144. {
  145.   if (idx >= array->elements)
  146.   {
  147.     if (idx >= array->max_element)
  148.     {
  149.       uint size;
  150.       char *new_ptr;
  151.       size=(idx+array->alloc_increment)/array->alloc_increment;
  152.       size*= array->alloc_increment;
  153.       if (!(new_ptr=(char*) my_realloc(array->buffer,size*
  154.        array->size_of_element,
  155.        MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
  156. return TRUE;
  157.       array->buffer=new_ptr;
  158.       array->max_element=size;
  159.     }
  160.     bzero((gptr) (array->buffer+array->elements*array->size_of_element),
  161.   (idx - array->elements)*array->size_of_element);
  162.     array->elements=idx+1;
  163.   }
  164.   memcpy(array->buffer+(idx * array->size_of_element),element,
  165.  (size_t) array->size_of_element);
  166.   return FALSE;
  167. }
  168. /*
  169.   Get an element from array by given index
  170.   SYNOPSIS
  171.     get_dynamic()
  172.       array
  173.       gptr Element to be returned. If idx > elements contain zeroes.
  174.       idx Index of element wanted. 
  175. */
  176. void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
  177. {
  178.   if (idx >= array->elements)
  179.   {
  180.     DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
  181.   idx,array->elements));
  182.     bzero(element,array->size_of_element);
  183.     return;
  184.   }
  185.   memcpy(element,array->buffer+idx*array->size_of_element,
  186.  (size_t) array->size_of_element);
  187. }
  188. /*
  189.   Empty array by freeing all memory
  190.   SYNOPSIS
  191.     delete_dynamic()
  192.       array Array to be deleted
  193. */
  194. void delete_dynamic(DYNAMIC_ARRAY *array)
  195. {
  196.   if (array->buffer)
  197.   {
  198.     my_free(array->buffer,MYF(MY_WME));
  199.     array->buffer=0;
  200.     array->elements=array->max_element=0;
  201.   }
  202. }
  203. /*
  204.   Delete element by given index
  205.   SYNOPSIS
  206.     delete_dynamic_element()
  207.       array
  208.       idx Index of element to be deleted
  209. */
  210. void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
  211. {
  212.   char *ptr=array->buffer+array->size_of_element*idx;
  213.   array->elements--;
  214.   memmove(ptr,ptr+array->size_of_element,
  215.   (array->elements-idx)*array->size_of_element);
  216. }
  217. /*
  218.   Free unused memory
  219.   SYNOPSIS
  220.     freeze_size()
  221.       array Array to be freed
  222. */
  223. void freeze_size(DYNAMIC_ARRAY *array)
  224. {
  225.   uint elements=max(array->elements,1);
  226.   if (array->buffer && array->max_element != elements)
  227.   {
  228.     array->buffer=(char*) my_realloc(array->buffer,
  229.      elements*array->size_of_element,
  230.      MYF(MY_WME));
  231.     array->max_element=elements;
  232.   }
  233. }