~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/* Handling of arrays that can grow dynamicly. */
17
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
18
#include "drizzled/internal/mysys_priv.h"
19
#include "drizzled/internal/m_string.h"
1 by brian
clean slate
20
1067.4.10 by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max.
21
#include <algorithm>
22
23
using namespace std;
24
1165.1.138 by Stewart Smith
make allocate_dynamic() static to mysys/dynamic_array.cc
25
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements);
26
1 by brian
clean slate
27
/*
28
  Initiate dynamic array
29
30
  SYNOPSIS
31
    init_dynamic_array2()
32
      array		Pointer to an array
33
      element_size	Size of element
34
      init_buffer       Initial buffer pointer
35
      init_alloc	Number of initial elements
36
      alloc_increment	Increment for adding new elements
37
38
  DESCRIPTION
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
39
    init_dynamic_array() initiates array and allocate space for
40
    init_alloc eilements.
1 by brian
clean slate
41
    Array is usable even if space allocation failed.
42
    Static buffers must begin immediately after the array structure.
43
44
  RETURN VALUE
656.3.2 by Monty Taylor
Removed my_nosys and my_quick. /me shudders.
45
    true	malloc() failed
163 by Brian Aker
Merge Monty's code.
46
    false	Ok
1 by brian
clean slate
47
*/
48
482 by Brian Aker
Remove uint.
49
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
50
                            void *init_buffer, uint32_t init_alloc,
575.1.6 by Monty Taylor
Cleaned up some headers for PCH.
51
                            uint32_t alloc_increment)
1 by brian
clean slate
52
{
53
  if (!alloc_increment)
54
  {
1067.4.10 by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max.
55
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16U);
1 by brian
clean slate
56
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
57
      alloc_increment=init_alloc*2;
58
  }
59
60
  if (!init_alloc)
61
  {
62
    init_alloc=alloc_increment;
63
    init_buffer= 0;
64
  }
65
  array->elements=0;
66
  array->max_element=init_alloc;
67
  array->alloc_increment=alloc_increment;
68
  array->size_of_element=element_size;
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
69
  if ((array->buffer= (unsigned char*) init_buffer))
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
70
    return(false);
656.3.2 by Monty Taylor
Removed my_nosys and my_quick. /me shudders.
71
  if (!(array->buffer=(unsigned char*) malloc(element_size*init_alloc)))
1 by brian
clean slate
72
  {
73
    array->max_element=0;
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
74
    return(true);
1 by brian
clean slate
75
  }
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
76
  return(false);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
77
}
1 by brian
clean slate
78
79
/*
80
  Insert element at the end of array. Allocate memory if needed.
81
82
  SYNOPSIS
83
    insert_dynamic()
84
      array
85
      element
86
87
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
88
    true	Insert failed
89
    false	Ok
1 by brian
clean slate
90
*/
91
481 by Brian Aker
Remove all of uchar.
92
bool insert_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
1 by brian
clean slate
93
{
481 by Brian Aker
Remove all of uchar.
94
  unsigned char* buffer;
1 by brian
clean slate
95
  if (array->elements == array->max_element)
96
  {						/* Call only when nessesary */
97
    if (!(buffer=alloc_dynamic(array)))
163 by Brian Aker
Merge Monty's code.
98
      return true;
1 by brian
clean slate
99
  }
100
  else
101
  {
102
    buffer=array->buffer+(array->elements * array->size_of_element);
103
    array->elements++;
104
  }
105
  memcpy(buffer,element,(size_t) array->size_of_element);
163 by Brian Aker
Merge Monty's code.
106
  return false;
1 by brian
clean slate
107
}
108
109
110
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
111
  Alloc space for next element(s)
1 by brian
clean slate
112
113
  SYNOPSIS
114
    alloc_dynamic()
115
      array
116
117
  DESCRIPTION
118
    alloc_dynamic() checks if there is empty space for at least
119
    one element if not tries to allocate space for alloc_increment
120
    elements at the end of array.
121
122
  RETURN VALUE
123
    pointer	Pointer to empty space for element
124
    0		Error
125
*/
126
481 by Brian Aker
Remove all of uchar.
127
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
1 by brian
clean slate
128
{
129
  if (array->elements == array->max_element)
130
  {
131
    char *new_ptr;
481 by Brian Aker
Remove all of uchar.
132
    if (array->buffer == (unsigned char *)(array + 1))
1 by brian
clean slate
133
    {
134
      /*
135
        In this senerio, the buffer is statically preallocated,
136
        so we have to create an all-new malloc since we overflowed
137
      */
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
138
      if (!(new_ptr= (char *) malloc((array->max_element+
139
                                     array->alloc_increment) *
140
                                     array->size_of_element)))
1 by brian
clean slate
141
        return 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
142
      memcpy(new_ptr, array->buffer,
1 by brian
clean slate
143
             array->elements * array->size_of_element);
144
    }
656.1.47 by Monty Taylor
More malloc return check fixes.
145
    else if (!(new_ptr= (char*) realloc(array->buffer,
146
                                        (array->max_element+
147
                                         array->alloc_increment)*
148
                                        array->size_of_element)))
1 by brian
clean slate
149
      return 0;
481 by Brian Aker
Remove all of uchar.
150
    array->buffer= (unsigned char*) new_ptr;
1 by brian
clean slate
151
    array->max_element+=array->alloc_increment;
152
  }
153
  return array->buffer+(array->elements++ * array->size_of_element);
154
}
155
156
157
/*
158
  Pop last element from array.
159
160
  SYNOPSIS
161
    pop_dynamic()
162
      array
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
163
164
  RETURN VALUE
1 by brian
clean slate
165
    pointer	Ok
166
    0		Array is empty
167
*/
168
481 by Brian Aker
Remove all of uchar.
169
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
1 by brian
clean slate
170
{
171
  if (array->elements)
172
    return array->buffer+(--array->elements * array->size_of_element);
173
  return 0;
174
}
175
176
/*
177
  Replace element in array with given element and index
178
179
  SYNOPSIS
180
    set_dynamic()
181
      array
182
      element	Element to be inserted
183
      idx	Index where element is to be inserted
184
185
  DESCRIPTION
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
186
    set_dynamic() replaces element in array.
187
    If idx > max_element insert new element. Allocate memory if needed.
188
1 by brian
clean slate
189
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
190
    true	Idx was out of range and allocation of new memory failed
191
    false	Ok
1 by brian
clean slate
192
*/
193
482 by Brian Aker
Remove uint.
194
bool set_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
1 by brian
clean slate
195
{
196
  if (idx >= array->elements)
197
  {
198
    if (idx >= array->max_element && allocate_dynamic(array, idx))
163 by Brian Aker
Merge Monty's code.
199
      return true;
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
200
    memset(array->buffer+array->elements*array->size_of_element, 0,
201
           (idx - array->elements)*array->size_of_element);
1 by brian
clean slate
202
    array->elements=idx+1;
203
  }
204
  memcpy(array->buffer+(idx * array->size_of_element),element,
205
	 (size_t) array->size_of_element);
163 by Brian Aker
Merge Monty's code.
206
  return false;
1 by brian
clean slate
207
}
208
209
210
/*
211
  Ensure that dynamic array has enough elements
212
213
  SYNOPSIS
214
    allocate_dynamic()
215
    array
216
    max_elements        Numbers of elements that is needed
217
218
  NOTES
219
   Any new allocated element are NOT initialized
220
221
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
222
    false	Ok
223
    true	Allocation of new memory failed
1 by brian
clean slate
224
*/
225
1165.1.138 by Stewart Smith
make allocate_dynamic() static to mysys/dynamic_array.cc
226
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
1 by brian
clean slate
227
{
228
  if (max_elements >= array->max_element)
229
  {
482 by Brian Aker
Remove uint.
230
    uint32_t size;
481 by Brian Aker
Remove all of uchar.
231
    unsigned char *new_ptr;
1 by brian
clean slate
232
    size= (max_elements + array->alloc_increment)/array->alloc_increment;
233
    size*= array->alloc_increment;
481 by Brian Aker
Remove all of uchar.
234
    if (array->buffer == (unsigned char *)(array + 1))
1 by brian
clean slate
235
    {
236
       /*
237
         In this senerio, the buffer is statically preallocated,
238
         so we have to create an all-new malloc since we overflowed
239
       */
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
240
       if (!(new_ptr= (unsigned char *) malloc(size *
241
                                               array->size_of_element)))
1 by brian
clean slate
242
         return 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
243
       memcpy(new_ptr, array->buffer,
1 by brian
clean slate
244
              array->elements * array->size_of_element);
245
     }
246
     else
247
248
656.1.47 by Monty Taylor
More malloc return check fixes.
249
    if (!(new_ptr=(unsigned char*) realloc(array->buffer,
250
                                        size* array->size_of_element)))
163 by Brian Aker
Merge Monty's code.
251
      return true;
1 by brian
clean slate
252
    array->buffer= new_ptr;
253
    array->max_element= size;
254
  }
163 by Brian Aker
Merge Monty's code.
255
  return false;
1 by brian
clean slate
256
}
257
258
259
/*
260
  Get an element from array by given index
261
262
  SYNOPSIS
263
    get_dynamic()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
264
      array
481 by Brian Aker
Remove all of uchar.
265
      unsigned char*	Element to be returned. If idx > elements contain zeroes.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
266
      idx	Index of element wanted.
1 by brian
clean slate
267
*/
268
482 by Brian Aker
Remove uint.
269
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
1 by brian
clean slate
270
{
271
  if (idx >= array->elements)
272
  {
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
273
    memset(element, 0, array->size_of_element);
1 by brian
clean slate
274
    return;
275
  }
276
  memcpy(element,array->buffer+idx*array->size_of_element,
277
         (size_t) array->size_of_element);
278
}
279
280
281
/*
282
  Empty array by freeing all memory
283
284
  SYNOPSIS
285
    delete_dynamic()
286
      array	Array to be deleted
287
*/
288
289
void delete_dynamic(DYNAMIC_ARRAY *array)
290
{
291
  /*
292
    Just mark as empty if we are using a static buffer
293
  */
481 by Brian Aker
Remove all of uchar.
294
  if (array->buffer == (unsigned char *)(array + 1))
1 by brian
clean slate
295
    array->elements= 0;
296
  else
297
  if (array->buffer)
298
  {
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
299
    free(array->buffer);
1 by brian
clean slate
300
    array->buffer=0;
301
    array->elements=array->max_element=0;
302
  }
303
}