~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/array.c

  • Committer: Brian Aker
  • Date: 2008-09-05 23:02:34 UTC
  • mfrom: (379 codestyle)
  • mto: This revision was merged to the branch mainline in revision 383.
  • Revision ID: brian@tangent.org-20080905230234-tq426zr79cnzjwo3
Merge from Monty, cleanup in tabs during merg.

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
 
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
54
 
                            void *init_buffer, uint32_t init_alloc,
55
 
                            uint32_t alloc_increment)
 
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)
56
46
{
57
47
  if (!alloc_increment)
58
48
  {
59
 
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16U);
 
49
    alloc_increment=max((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=(uchar*) 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, 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
81
}
82
 
 
83
82
/*
84
83
  Insert element at the end of array. Allocate memory if needed.
85
84
 
93
92
    false       Ok
94
93
*/
95
94
 
96
 
bool insert_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
 
95
bool insert_dynamic(DYNAMIC_ARRAY *array, uchar* element)
97
96
{
98
 
  unsigned char* buffer;
 
97
  uchar* buffer;
99
98
  if (array->elements == array->max_element)
100
99
  {                                             /* Call only when nessesary */
101
100
    if (!(buffer=alloc_dynamic(array)))
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()
128
127
    0           Error
129
128
*/
130
129
 
131
 
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
 
130
uchar *alloc_dynamic(DYNAMIC_ARRAY *array)
132
131
{
133
132
  if (array->elements == array->max_element)
134
133
  {
135
134
    char *new_ptr;
136
 
    if (array->buffer == (unsigned char *)(array + 1))
 
135
    if (array->buffer == (uchar *)(array + 1))
137
136
    {
138
137
      /*
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
 
    array->buffer= (unsigned char*) new_ptr;
 
155
    array->buffer= (uchar*) new_ptr;
155
156
    array->max_element+=array->alloc_increment;
156
157
  }
157
158
  return array->buffer+(array->elements++ * array->size_of_element);
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
*/
172
173
 
173
 
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
 
174
uchar *pop_dynamic(DYNAMIC_ARRAY *array)
174
175
{
175
176
  if (array->elements)
176
177
    return array->buffer+(--array->elements * array->size_of_element);
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
196
197
*/
197
198
 
198
 
bool set_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
 
199
bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
199
200
{
200
201
  if (idx >= array->elements)
201
202
  {
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, uint max_elements)
231
232
{
232
233
  if (max_elements >= array->max_element)
233
234
  {
234
 
    uint32_t size;
235
 
    unsigned char *new_ptr;
 
235
    uint size;
 
236
    uchar *new_ptr;
236
237
    size= (max_elements + array->alloc_increment)/array->alloc_increment;
237
238
    size*= array->alloc_increment;
238
 
    if (array->buffer == (unsigned char *)(array + 1))
 
239
    if (array->buffer == (uchar *)(array + 1))
239
240
    {
240
241
       /*
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= (uchar *) 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= (uchar*) 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
269
 
      unsigned char*    Element to be returned. If idx > elements contain zeroes.
270
 
      idx       Index of element wanted.
 
271
      array     
 
272
      uchar*    Element to be returned. If idx > elements contain zeroes.
 
273
      idx       Index of element wanted. 
271
274
*/
272
275
 
273
 
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
 
276
void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
274
277
{
275
278
  if (idx >= array->elements)
276
279
  {
295
298
  /*
296
299
    Just mark as empty if we are using a static buffer
297
300
  */
298
 
  if (array->buffer == (unsigned char *)(array + 1))
 
301
  if (array->buffer == (uchar *)(array + 1))
299
302
    array->elements= 0;
300
303
  else
301
304
  if (array->buffer)
302
305
  {
303
 
    free(array->buffer);
 
306
    my_free(array->buffer,MYF(MY_WME));
304
307
    array->buffer=0;
305
308
    array->elements=array->max_element=0;
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, 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
}