~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/dynamic_array.cc

  • Committer: Monty Taylor
  • Date: 2009-12-22 20:47:20 UTC
  • mto: This revision was merged to the branch mainline in revision 1253.
  • Revision ID: mordred@inaugust.com-20091222204720-7ynx08xryaihgj8h
Removed one more public IO_CACHE.

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