~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/array.c

  • Committer: Jay Pipes
  • Date: 2008-07-17 18:48:58 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717184858-2mbouxl8xi41gcge
Removed DBUG from CSV and Blackhole storage engines

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 "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
{
 
47
  DBUG_ENTER("init_dynamic_array");
57
48
  if (!alloc_increment)
58
49
  {
59
 
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16U);
 
50
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
60
51
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
61
52
      alloc_increment=init_alloc*2;
62
53
  }
70
61
  array->max_element=init_alloc;
71
62
  array->alloc_increment=alloc_increment;
72
63
  array->size_of_element=element_size;
73
 
  if ((array->buffer= (unsigned char*) init_buffer))
74
 
    return(false);
75
 
  if (!(array->buffer=(unsigned char*) malloc(element_size*init_alloc)))
 
64
  if ((array->buffer= init_buffer))
 
65
    DBUG_RETURN(false);
 
66
  if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc,
 
67
                                            MYF(MY_WME))))
76
68
  {
77
69
    array->max_element=0;
78
 
    return(true);
 
70
    DBUG_RETURN(true);
79
71
  }
80
 
  return(false);
 
72
  DBUG_RETURN(false);
 
73
 
74
 
 
75
bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
 
76
                           uint init_alloc, 
 
77
                           uint alloc_increment CALLER_INFO_PROTO)
 
78
{
 
79
  /* placeholder to preserve ABI */
 
80
  return my_init_dynamic_array_ci(array, element_size, init_alloc, 
 
81
                                  alloc_increment);
81
82
}
82
 
 
83
83
/*
84
84
  Insert element at the end of array. Allocate memory if needed.
85
85
 
93
93
    false       Ok
94
94
*/
95
95
 
96
 
bool insert_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
 
96
bool insert_dynamic(DYNAMIC_ARRAY *array, uchar* element)
97
97
{
98
 
  unsigned char* buffer;
 
98
  uchar* buffer;
99
99
  if (array->elements == array->max_element)
100
100
  {                                             /* Call only when nessesary */
101
101
    if (!(buffer=alloc_dynamic(array)))
112
112
 
113
113
 
114
114
/*
115
 
  Alloc space for next element(s)
 
115
  Alloc space for next element(s) 
116
116
 
117
117
  SYNOPSIS
118
118
    alloc_dynamic()
128
128
    0           Error
129
129
*/
130
130
 
131
 
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
 
131
uchar *alloc_dynamic(DYNAMIC_ARRAY *array)
132
132
{
133
133
  if (array->elements == array->max_element)
134
134
  {
135
135
    char *new_ptr;
136
 
    if (array->buffer == (unsigned char *)(array + 1))
 
136
    if (array->buffer == (uchar *)(array + 1))
137
137
    {
138
138
      /*
139
139
        In this senerio, the buffer is statically preallocated,
140
140
        so we have to create an all-new malloc since we overflowed
141
141
      */
142
 
      if (!(new_ptr= (char *) malloc((array->max_element+
143
 
                                     array->alloc_increment) *
144
 
                                     array->size_of_element)))
 
142
      if (!(new_ptr= (char *) my_malloc((array->max_element+
 
143
                                         array->alloc_increment) *
 
144
                                        array->size_of_element,
 
145
                                        MYF(MY_WME))))
145
146
        return 0;
146
 
      memcpy(new_ptr, array->buffer,
 
147
      memcpy(new_ptr, array->buffer, 
147
148
             array->elements * array->size_of_element);
148
149
    }
149
 
    else if (!(new_ptr= (char*) realloc(array->buffer,
150
 
                                        (array->max_element+
151
 
                                         array->alloc_increment)*
152
 
                                        array->size_of_element)))
 
150
    else
 
151
    if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
 
152
                                     array->alloc_increment)*
 
153
                                     array->size_of_element,
 
154
                                     MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
153
155
      return 0;
154
 
    array->buffer= (unsigned char*) new_ptr;
 
156
    array->buffer= (uchar*) new_ptr;
155
157
    array->max_element+=array->alloc_increment;
156
158
  }
157
159
  return array->buffer+(array->elements++ * array->size_of_element);
164
166
  SYNOPSIS
165
167
    pop_dynamic()
166
168
      array
167
 
 
168
 
  RETURN VALUE
 
169
  
 
170
  RETURN VALUE    
169
171
    pointer     Ok
170
172
    0           Array is empty
171
173
*/
172
174
 
173
 
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
 
175
uchar *pop_dynamic(DYNAMIC_ARRAY *array)
174
176
{
175
177
  if (array->elements)
176
178
    return array->buffer+(--array->elements * array->size_of_element);
187
189
      idx       Index where element is to be inserted
188
190
 
189
191
  DESCRIPTION
190
 
    set_dynamic() replaces element in array.
191
 
    If idx > max_element insert new element. Allocate memory if needed.
192
 
 
 
192
    set_dynamic() replaces element in array. 
 
193
    If idx > max_element insert new element. Allocate memory if needed. 
 
194
 
193
195
  RETURN VALUE
194
196
    true        Idx was out of range and allocation of new memory failed
195
197
    false       Ok
196
198
*/
197
199
 
198
 
bool set_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
 
200
bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
199
201
{
200
202
  if (idx >= array->elements)
201
203
  {
202
204
    if (idx >= array->max_element && allocate_dynamic(array, idx))
203
205
      return true;
204
 
    memset(array->buffer+array->elements*array->size_of_element, 0,
205
 
           (idx - array->elements)*array->size_of_element);
 
206
    bzero((uchar*) (array->buffer+array->elements*array->size_of_element),
 
207
          (idx - array->elements)*array->size_of_element);
206
208
    array->elements=idx+1;
207
209
  }
208
210
  memcpy(array->buffer+(idx * array->size_of_element),element,
227
229
    true        Allocation of new memory failed
228
230
*/
229
231
 
230
 
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
 
232
bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
231
233
{
232
234
  if (max_elements >= array->max_element)
233
235
  {
234
 
    uint32_t size;
235
 
    unsigned char *new_ptr;
 
236
    uint size;
 
237
    uchar *new_ptr;
236
238
    size= (max_elements + array->alloc_increment)/array->alloc_increment;
237
239
    size*= array->alloc_increment;
238
 
    if (array->buffer == (unsigned char *)(array + 1))
 
240
    if (array->buffer == (uchar *)(array + 1))
239
241
    {
240
242
       /*
241
243
         In this senerio, the buffer is statically preallocated,
242
244
         so we have to create an all-new malloc since we overflowed
243
245
       */
244
 
       if (!(new_ptr= (unsigned char *) malloc(size *
245
 
                                               array->size_of_element)))
 
246
       if (!(new_ptr= (uchar *) my_malloc(size *
 
247
                                         array->size_of_element,
 
248
                                         MYF(MY_WME))))
246
249
         return 0;
247
 
       memcpy(new_ptr, array->buffer,
 
250
       memcpy(new_ptr, array->buffer, 
248
251
              array->elements * array->size_of_element);
249
252
     }
250
253
     else
251
254
 
252
255
 
253
 
    if (!(new_ptr=(unsigned char*) realloc(array->buffer,
254
 
                                        size* array->size_of_element)))
 
256
    if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
 
257
                                       array->size_of_element,
 
258
                                       MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
255
259
      return true;
256
260
    array->buffer= new_ptr;
257
261
    array->max_element= size;
265
269
 
266
270
  SYNOPSIS
267
271
    get_dynamic()
268
 
      array
269
 
      unsigned char*    Element to be returned. If idx > elements contain zeroes.
270
 
      idx       Index of element wanted.
 
272
      array     
 
273
      uchar*    Element to be returned. If idx > elements contain zeroes.
 
274
      idx       Index of element wanted. 
271
275
*/
272
276
 
273
 
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
 
277
void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
274
278
{
275
279
  if (idx >= array->elements)
276
280
  {
277
 
    memset(element, 0, array->size_of_element);
 
281
    DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
 
282
                          idx,array->elements));
 
283
    bzero(element,array->size_of_element);
278
284
    return;
279
285
  }
280
286
  memcpy(element,array->buffer+idx*array->size_of_element,
295
301
  /*
296
302
    Just mark as empty if we are using a static buffer
297
303
  */
298
 
  if (array->buffer == (unsigned char *)(array + 1))
 
304
  if (array->buffer == (uchar *)(array + 1))
299
305
    array->elements= 0;
300
306
  else
301
307
  if (array->buffer)
302
308
  {
303
 
    free(array->buffer);
 
309
    my_free(array->buffer,MYF(MY_WME));
304
310
    array->buffer=0;
305
311
    array->elements=array->max_element=0;
306
312
  }
307
313
}
308
314
 
309
 
} /* namespace drizzled */
 
315
/*
 
316
  Delete element by given index
 
317
 
 
318
  SYNOPSIS
 
319
    delete_dynamic_element()
 
320
      array
 
321
      idx        Index of element to be deleted
 
322
*/
 
323
 
 
324
void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
 
325
{
 
326
  char *ptr= (char*) array->buffer+array->size_of_element*idx;
 
327
  array->elements--;
 
328
  memmove(ptr,ptr+array->size_of_element,
 
329
          (array->elements-idx)*array->size_of_element);
 
330
}
 
331
 
 
332
 
 
333
/*
 
334
  Free unused memory
 
335
 
 
336
  SYNOPSIS
 
337
    freeze_size()
 
338
      array     Array to be freed
 
339
 
 
340
*/
 
341
 
 
342
void freeze_size(DYNAMIC_ARRAY *array)
 
343
{
 
344
  uint elements=max(array->elements,1);
 
345
 
 
346
  /*
 
347
    Do nothing if we are using a static buffer
 
348
  */
 
349
  if (array->buffer == (uchar *)(array + 1))
 
350
    return;
 
351
    
 
352
  if (array->buffer && array->max_element != elements)
 
353
  {
 
354
    array->buffer=(uchar*) my_realloc(array->buffer,
 
355
                                     elements*array->size_of_element,
 
356
                                     MYF(MY_WME));
 
357
    array->max_element=elements;
 
358
  }
 
359
}
 
360
 
 
361
 
 
362
/*
 
363
  Get the index of a dynamic element
 
364
 
 
365
  SYNOPSIS
 
366
    get_index_dynamic()
 
367
     array      Array
 
368
     element Whose element index 
 
369
 
 
370
*/
 
371
 
 
372
int get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element)
 
373
{
 
374
  uint ret;
 
375
  if (array->buffer > element)
 
376
    return -1;
 
377
 
 
378
  ret= (element - array->buffer) /  array->size_of_element;
 
379
  if (ret > array->elements)
 
380
    return -1;
 
381
 
 
382
  return ret;
 
383
 
 
384
}