~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/array.c

Merged vcol stuff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/* Handling of arrays that can grow dynamicly. */
17
17
 
18
 
#include "config.h"
19
 
#include "drizzled/internal/my_sys.h"
20
 
#include "drizzled/internal/m_string.h"
21
 
 
22
 
#include <algorithm>
23
 
 
24
 
using namespace std;
25
 
 
26
 
namespace drizzled
27
 
{
28
 
 
29
 
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements);
 
18
#include "mysys_priv.h"
 
19
#include <mystrings/m_string.h>
30
20
 
31
21
/*
32
22
  Initiate dynamic array
40
30
      alloc_increment   Increment for adding new elements
41
31
 
42
32
  DESCRIPTION
43
 
    init_dynamic_array() initiates array and allocate space for
44
 
    init_alloc eilements.
 
33
    init_dynamic_array() initiates array and allocate space for 
 
34
    init_alloc eilements. 
45
35
    Array is usable even if space allocation failed.
46
36
    Static buffers must begin immediately after the array structure.
47
37
 
48
38
  RETURN VALUE
49
 
    true        malloc() failed
 
39
    true        my_malloc_ci() failed
50
40
    false       Ok
51
41
*/
52
42
 
53
43
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
54
 
                            void *init_buffer, uint32_t init_alloc,
55
 
                            uint32_t alloc_increment)
 
44
                            void *init_buffer, uint32_t init_alloc, 
 
45
                            uint32_t alloc_increment CALLER_INFO_PROTO)
56
46
{
57
47
  if (!alloc_increment)
58
48
  {
59
 
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16U);
 
49
    alloc_increment=cmax((8192-MALLOC_OVERHEAD)/element_size,16);
60
50
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
61
51
      alloc_increment=init_alloc*2;
62
52
  }
70
60
  array->max_element=init_alloc;
71
61
  array->alloc_increment=alloc_increment;
72
62
  array->size_of_element=element_size;
73
 
  if ((array->buffer= (unsigned char*) init_buffer))
 
63
  if ((array->buffer= init_buffer))
74
64
    return(false);
75
 
  if (!(array->buffer=(unsigned char*) malloc(element_size*init_alloc)))
 
65
  if (!(array->buffer=(unsigned char*) my_malloc_ci(element_size*init_alloc,
 
66
                                            MYF(MY_WME))))
76
67
  {
77
68
    array->max_element=0;
78
69
    return(true);
79
70
  }
80
71
  return(false);
 
72
 
73
 
 
74
bool init_dynamic_array(DYNAMIC_ARRAY *array, uint32_t element_size,
 
75
                           uint32_t init_alloc, 
 
76
                           uint32_t alloc_increment CALLER_INFO_PROTO)
 
77
{
 
78
  /* placeholder to preserve ABI */
 
79
  return my_init_dynamic_array_ci(array, element_size, init_alloc, 
 
80
                                  alloc_increment);
81
81
}
82
 
 
83
82
/*
84
83
  Insert element at the end of array. Allocate memory if needed.
85
84
 
112
111
 
113
112
 
114
113
/*
115
 
  Alloc space for next element(s)
 
114
  Alloc space for next element(s) 
116
115
 
117
116
  SYNOPSIS
118
117
    alloc_dynamic()
139
138
        In this senerio, the buffer is statically preallocated,
140
139
        so we have to create an all-new malloc since we overflowed
141
140
      */
142
 
      if (!(new_ptr= (char *) malloc((array->max_element+
143
 
                                     array->alloc_increment) *
144
 
                                     array->size_of_element)))
 
141
      if (!(new_ptr= (char *) my_malloc((array->max_element+
 
142
                                         array->alloc_increment) *
 
143
                                        array->size_of_element,
 
144
                                        MYF(MY_WME))))
145
145
        return 0;
146
 
      memcpy(new_ptr, array->buffer,
 
146
      memcpy(new_ptr, array->buffer, 
147
147
             array->elements * array->size_of_element);
148
148
    }
149
 
    else if (!(new_ptr= (char*) realloc(array->buffer,
150
 
                                        (array->max_element+
151
 
                                         array->alloc_increment)*
152
 
                                        array->size_of_element)))
 
149
    else
 
150
    if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
 
151
                                     array->alloc_increment)*
 
152
                                     array->size_of_element,
 
153
                                     MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
153
154
      return 0;
154
155
    array->buffer= (unsigned char*) new_ptr;
155
156
    array->max_element+=array->alloc_increment;
164
165
  SYNOPSIS
165
166
    pop_dynamic()
166
167
      array
167
 
 
168
 
  RETURN VALUE
 
168
  
 
169
  RETURN VALUE    
169
170
    pointer     Ok
170
171
    0           Array is empty
171
172
*/
187
188
      idx       Index where element is to be inserted
188
189
 
189
190
  DESCRIPTION
190
 
    set_dynamic() replaces element in array.
191
 
    If idx > max_element insert new element. Allocate memory if needed.
192
 
 
 
191
    set_dynamic() replaces element in array. 
 
192
    If idx > max_element insert new element. Allocate memory if needed. 
 
193
 
193
194
  RETURN VALUE
194
195
    true        Idx was out of range and allocation of new memory failed
195
196
    false       Ok
227
228
    true        Allocation of new memory failed
228
229
*/
229
230
 
230
 
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
 
231
bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
231
232
{
232
233
  if (max_elements >= array->max_element)
233
234
  {
241
242
         In this senerio, the buffer is statically preallocated,
242
243
         so we have to create an all-new malloc since we overflowed
243
244
       */
244
 
       if (!(new_ptr= (unsigned char *) malloc(size *
245
 
                                               array->size_of_element)))
 
245
       if (!(new_ptr= (unsigned char *) my_malloc(size *
 
246
                                         array->size_of_element,
 
247
                                         MYF(MY_WME))))
246
248
         return 0;
247
 
       memcpy(new_ptr, array->buffer,
 
249
       memcpy(new_ptr, array->buffer, 
248
250
              array->elements * array->size_of_element);
249
251
     }
250
252
     else
251
253
 
252
254
 
253
 
    if (!(new_ptr=(unsigned char*) realloc(array->buffer,
254
 
                                        size* array->size_of_element)))
 
255
    if (!(new_ptr= (unsigned char*) my_realloc(array->buffer,size*
 
256
                                       array->size_of_element,
 
257
                                       MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
255
258
      return true;
256
259
    array->buffer= new_ptr;
257
260
    array->max_element= size;
265
268
 
266
269
  SYNOPSIS
267
270
    get_dynamic()
268
 
      array
 
271
      array     
269
272
      unsigned char*    Element to be returned. If idx > elements contain zeroes.
270
 
      idx       Index of element wanted.
 
273
      idx       Index of element wanted. 
271
274
*/
272
275
 
273
276
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
306
309
  }
307
310
}
308
311
 
309
 
} /* namespace drizzled */
 
312
/*
 
313
  Delete element by given index
 
314
 
 
315
  SYNOPSIS
 
316
    delete_dynamic_element()
 
317
      array
 
318
      idx        Index of element to be deleted
 
319
*/
 
320
 
 
321
void delete_dynamic_element(DYNAMIC_ARRAY *array, uint32_t idx)
 
322
{
 
323
  char *ptr= (char*) array->buffer+array->size_of_element*idx;
 
324
  array->elements--;
 
325
  memmove(ptr,ptr+array->size_of_element,
 
326
          (array->elements-idx)*array->size_of_element);
 
327
}
 
328
 
 
329
 
 
330
/*
 
331
  Free unused memory
 
332
 
 
333
  SYNOPSIS
 
334
    freeze_size()
 
335
      array     Array to be freed
 
336
 
 
337
*/
 
338
 
 
339
void freeze_size(DYNAMIC_ARRAY *array)
 
340
{
 
341
  uint32_t elements=cmax(array->elements,1);
 
342
 
 
343
  /*
 
344
    Do nothing if we are using a static buffer
 
345
  */
 
346
  if (array->buffer == (unsigned char *)(array + 1))
 
347
    return;
 
348
    
 
349
  if (array->buffer && array->max_element != elements)
 
350
  {
 
351
    array->buffer=(unsigned char*) my_realloc(array->buffer,
 
352
                                     elements*array->size_of_element,
 
353
                                     MYF(MY_WME));
 
354
    array->max_element=elements;
 
355
  }
 
356
}
 
357
 
 
358
 
 
359
/*
 
360
  Get the index of a dynamic element
 
361
 
 
362
  SYNOPSIS
 
363
    get_index_dynamic()
 
364
     array      Array
 
365
     element Whose element index 
 
366
 
 
367
*/
 
368
 
 
369
int get_index_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
 
370
{
 
371
  uint32_t ret;
 
372
  if (array->buffer > element)
 
373
    return -1;
 
374
 
 
375
  ret= (element - array->buffer) /  array->size_of_element;
 
376
  if (ret > array->elements)
 
377
    return -1;
 
378
 
 
379
  return ret;
 
380
 
 
381
}