~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/array.cc

  • Committer: Brian Aker
  • Date: 2009-07-11 08:51:36 UTC
  • mfrom: (1089.3.11 merge)
  • Revision ID: brian@gaz-20090711085136-qj01nwm3qynghwtc
Merge Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* Handling of arrays that can grow dynamicly. */
17
17
 
18
 
#include "mysys_priv.h"
 
18
#include "mysys/mysys_priv.h"
19
19
#include <mystrings/m_string.h>
20
20
 
 
21
#include <algorithm>
 
22
 
 
23
using namespace std;
 
24
 
21
25
/*
22
26
  Initiate dynamic array
23
27
 
30
34
      alloc_increment   Increment for adding new elements
31
35
 
32
36
  DESCRIPTION
33
 
    init_dynamic_array() initiates array and allocate space for 
34
 
    init_alloc eilements. 
 
37
    init_dynamic_array() initiates array and allocate space for
 
38
    init_alloc eilements.
35
39
    Array is usable even if space allocation failed.
36
40
    Static buffers must begin immediately after the array structure.
37
41
 
38
42
  RETURN VALUE
39
 
    true        my_malloc_ci() failed
 
43
    true        malloc() failed
40
44
    false       Ok
41
45
*/
42
46
 
43
 
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
44
 
                            void *init_buffer, uint init_alloc, 
45
 
                            uint alloc_increment CALLER_INFO_PROTO)
 
47
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
 
48
                            void *init_buffer, uint32_t init_alloc,
 
49
                            uint32_t alloc_increment)
46
50
{
47
51
  if (!alloc_increment)
48
52
  {
49
 
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
 
53
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16U);
50
54
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
51
55
      alloc_increment=init_alloc*2;
52
56
  }
60
64
  array->max_element=init_alloc;
61
65
  array->alloc_increment=alloc_increment;
62
66
  array->size_of_element=element_size;
63
 
  if ((array->buffer= init_buffer))
 
67
  if ((array->buffer= (unsigned char*) init_buffer))
64
68
    return(false);
65
 
  if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc,
66
 
                                            MYF(MY_WME))))
 
69
  if (!(array->buffer=(unsigned char*) malloc(element_size*init_alloc)))
67
70
  {
68
71
    array->max_element=0;
69
72
    return(true);
70
73
  }
71
74
  return(false);
72
 
 
75
}
73
76
 
74
 
bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
75
 
                           uint init_alloc, 
76
 
                           uint 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
 
}
82
77
/*
83
78
  Insert element at the end of array. Allocate memory if needed.
84
79
 
92
87
    false       Ok
93
88
*/
94
89
 
95
 
bool insert_dynamic(DYNAMIC_ARRAY *array, uchar* element)
 
90
bool insert_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
96
91
{
97
 
  uchar* buffer;
 
92
  unsigned char* buffer;
98
93
  if (array->elements == array->max_element)
99
94
  {                                             /* Call only when nessesary */
100
95
    if (!(buffer=alloc_dynamic(array)))
111
106
 
112
107
 
113
108
/*
114
 
  Alloc space for next element(s) 
 
109
  Alloc space for next element(s)
115
110
 
116
111
  SYNOPSIS
117
112
    alloc_dynamic()
127
122
    0           Error
128
123
*/
129
124
 
130
 
uchar *alloc_dynamic(DYNAMIC_ARRAY *array)
 
125
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
131
126
{
132
127
  if (array->elements == array->max_element)
133
128
  {
134
129
    char *new_ptr;
135
 
    if (array->buffer == (uchar *)(array + 1))
 
130
    if (array->buffer == (unsigned char *)(array + 1))
136
131
    {
137
132
      /*
138
133
        In this senerio, the buffer is statically preallocated,
139
134
        so we have to create an all-new malloc since we overflowed
140
135
      */
141
 
      if (!(new_ptr= (char *) my_malloc((array->max_element+
142
 
                                         array->alloc_increment) *
143
 
                                        array->size_of_element,
144
 
                                        MYF(MY_WME))))
 
136
      if (!(new_ptr= (char *) malloc((array->max_element+
 
137
                                     array->alloc_increment) *
 
138
                                     array->size_of_element)))
145
139
        return 0;
146
 
      memcpy(new_ptr, array->buffer, 
 
140
      memcpy(new_ptr, array->buffer,
147
141
             array->elements * array->size_of_element);
148
142
    }
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))))
 
143
    else if (!(new_ptr= (char*) realloc(array->buffer,
 
144
                                        (array->max_element+
 
145
                                         array->alloc_increment)*
 
146
                                        array->size_of_element)))
154
147
      return 0;
155
 
    array->buffer= (uchar*) new_ptr;
 
148
    array->buffer= (unsigned char*) new_ptr;
156
149
    array->max_element+=array->alloc_increment;
157
150
  }
158
151
  return array->buffer+(array->elements++ * array->size_of_element);
165
158
  SYNOPSIS
166
159
    pop_dynamic()
167
160
      array
168
 
  
169
 
  RETURN VALUE    
 
161
 
 
162
  RETURN VALUE
170
163
    pointer     Ok
171
164
    0           Array is empty
172
165
*/
173
166
 
174
 
uchar *pop_dynamic(DYNAMIC_ARRAY *array)
 
167
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
175
168
{
176
169
  if (array->elements)
177
170
    return array->buffer+(--array->elements * array->size_of_element);
188
181
      idx       Index where element is to be inserted
189
182
 
190
183
  DESCRIPTION
191
 
    set_dynamic() replaces element in array. 
192
 
    If idx > max_element insert new element. Allocate memory if needed. 
193
 
 
 
184
    set_dynamic() replaces element in array.
 
185
    If idx > max_element insert new element. Allocate memory if needed.
 
186
 
194
187
  RETURN VALUE
195
188
    true        Idx was out of range and allocation of new memory failed
196
189
    false       Ok
197
190
*/
198
191
 
199
 
bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
 
192
bool set_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
200
193
{
201
194
  if (idx >= array->elements)
202
195
  {
228
221
    true        Allocation of new memory failed
229
222
*/
230
223
 
231
 
bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
 
224
bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
232
225
{
233
226
  if (max_elements >= array->max_element)
234
227
  {
235
 
    uint size;
236
 
    uchar *new_ptr;
 
228
    uint32_t size;
 
229
    unsigned char *new_ptr;
237
230
    size= (max_elements + array->alloc_increment)/array->alloc_increment;
238
231
    size*= array->alloc_increment;
239
 
    if (array->buffer == (uchar *)(array + 1))
 
232
    if (array->buffer == (unsigned char *)(array + 1))
240
233
    {
241
234
       /*
242
235
         In this senerio, the buffer is statically preallocated,
243
236
         so we have to create an all-new malloc since we overflowed
244
237
       */
245
 
       if (!(new_ptr= (uchar *) my_malloc(size *
246
 
                                         array->size_of_element,
247
 
                                         MYF(MY_WME))))
 
238
       if (!(new_ptr= (unsigned char *) malloc(size *
 
239
                                               array->size_of_element)))
248
240
         return 0;
249
 
       memcpy(new_ptr, array->buffer, 
 
241
       memcpy(new_ptr, array->buffer,
250
242
              array->elements * array->size_of_element);
251
243
     }
252
244
     else
253
245
 
254
246
 
255
 
    if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
256
 
                                       array->size_of_element,
257
 
                                       MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
 
247
    if (!(new_ptr=(unsigned char*) realloc(array->buffer,
 
248
                                        size* array->size_of_element)))
258
249
      return true;
259
250
    array->buffer= new_ptr;
260
251
    array->max_element= size;
268
259
 
269
260
  SYNOPSIS
270
261
    get_dynamic()
271
 
      array     
272
 
      uchar*    Element to be returned. If idx > elements contain zeroes.
273
 
      idx       Index of element wanted. 
 
262
      array
 
263
      unsigned char*    Element to be returned. If idx > elements contain zeroes.
 
264
      idx       Index of element wanted.
274
265
*/
275
266
 
276
 
void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
 
267
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
277
268
{
278
269
  if (idx >= array->elements)
279
270
  {
298
289
  /*
299
290
    Just mark as empty if we are using a static buffer
300
291
  */
301
 
  if (array->buffer == (uchar *)(array + 1))
 
292
  if (array->buffer == (unsigned char *)(array + 1))
302
293
    array->elements= 0;
303
294
  else
304
295
  if (array->buffer)
305
296
  {
306
 
    my_free(array->buffer,MYF(MY_WME));
 
297
    free(array->buffer);
307
298
    array->buffer=0;
308
299
    array->elements=array->max_element=0;
309
300
  }
310
301
}
311
 
 
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, uint 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
 
  uint elements=max(array->elements,1);
342
 
 
343
 
  /*
344
 
    Do nothing if we are using a static buffer
345
 
  */
346
 
  if (array->buffer == (uchar *)(array + 1))
347
 
    return;
348
 
    
349
 
  if (array->buffer && array->max_element != elements)
350
 
  {
351
 
    array->buffer=(uchar*) 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, uchar* element)
370
 
{
371
 
  uint 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
 
}