~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/dynamic_array.cc

  • Committer: Stewart Smith
  • Date: 2010-02-22 07:44:37 UTC
  • mfrom: (1283.17.4)
  • mto: (1283.19.1)
  • mto: This revision was merged to the branch mainline in revision 1449.
  • Revision ID: stewart@flamingspork.com-20100222074437-1a9x1n030tbtv1qv
Merged embeddded-innodb-store-table-proto into embedded-innodb-write-row.

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>
 
18
#include "config.h"
 
19
#include "drizzled/internal/my_sys.h"
 
20
#include "drizzled/internal/m_string.h"
 
21
 
19
22
#include <algorithm>
20
 
#include <drizzled/dynamic_array.h>
21
 
#include <drizzled/internal/my_sys.h>
22
23
 
23
24
using namespace std;
24
25
 
25
 
namespace drizzled {
 
26
namespace drizzled
 
27
{
 
28
 
 
29
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements);
26
30
 
27
31
/*
28
32
  Initiate dynamic array
46
50
    false       Ok
47
51
*/
48
52
 
49
 
void init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
 
53
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
50
54
                            void *init_buffer, uint32_t init_alloc,
51
55
                            uint32_t alloc_increment)
52
56
{
62
66
    init_alloc=alloc_increment;
63
67
    init_buffer= 0;
64
68
  }
65
 
  array->set_size(0);
 
69
  array->elements=0;
66
70
  array->max_element=init_alloc;
67
71
  array->alloc_increment=alloc_increment;
68
72
  array->size_of_element=element_size;
69
73
  if ((array->buffer= (unsigned char*) init_buffer))
70
 
    return;
71
 
  array->buffer= (unsigned char*) malloc(element_size*init_alloc);
 
74
    return(false);
 
75
  if (!(array->buffer=(unsigned char*) malloc(element_size*init_alloc)))
 
76
  {
 
77
    array->max_element=0;
 
78
    return(true);
 
79
  }
 
80
  return(false);
72
81
}
73
82
 
74
83
/*
84
93
    false       Ok
85
94
*/
86
95
 
87
 
static void insert_dynamic(DYNAMIC_ARRAY *array, void* element)
 
96
bool insert_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
88
97
{
89
98
  unsigned char* buffer;
90
 
  if (array->size() == array->max_element)
91
 
    buffer= alloc_dynamic(array);
 
99
  if (array->elements == array->max_element)
 
100
  {                                             /* Call only when nessesary */
 
101
    if (!(buffer=alloc_dynamic(array)))
 
102
      return true;
 
103
  }
92
104
  else
93
105
  {
94
 
    buffer= array->buffer+(array->size() * array->size_of_element);
95
 
    array->set_size(array->size() + 1);
 
106
    buffer=array->buffer+(array->elements * array->size_of_element);
 
107
    array->elements++;
96
108
  }
97
 
  memcpy(buffer,element, array->size_of_element);
98
 
}
99
 
 
100
 
void DYNAMIC_ARRAY::push_back(void* v)
101
 
{
102
 
  insert_dynamic(this, v);
 
109
  memcpy(buffer,element,(size_t) array->size_of_element);
 
110
  return false;
103
111
}
104
112
 
105
113
 
122
130
 
123
131
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
124
132
{
125
 
  if (array->size() == array->max_element)
 
133
  if (array->elements == array->max_element)
126
134
  {
127
135
    char *new_ptr;
128
136
    if (array->buffer == (unsigned char *)(array + 1))
131
139
        In this senerio, the buffer is statically preallocated,
132
140
        so we have to create an all-new malloc since we overflowed
133
141
      */
134
 
      new_ptr= (char*) malloc((array->max_element + array->alloc_increment) * array->size_of_element);
135
 
      memcpy(new_ptr, array->buffer, array->size() * array->size_of_element);
 
142
      if (!(new_ptr= (char *) malloc((array->max_element+
 
143
                                     array->alloc_increment) *
 
144
                                     array->size_of_element)))
 
145
        return 0;
 
146
      memcpy(new_ptr, array->buffer,
 
147
             array->elements * array->size_of_element);
136
148
    }
137
 
    else 
138
 
      new_ptr= (char*) realloc(array->buffer, (array->max_element + array->alloc_increment) * array->size_of_element);
 
149
    else if (!(new_ptr= (char*) realloc(array->buffer,
 
150
                                        (array->max_element+
 
151
                                         array->alloc_increment)*
 
152
                                        array->size_of_element)))
 
153
      return 0;
139
154
    array->buffer= (unsigned char*) new_ptr;
140
155
    array->max_element+=array->alloc_increment;
141
156
  }
142
 
  array->set_size(array->size() + 1);
143
 
  return array->buffer + ((array->size() - 1) * array->size_of_element);
144
 
}
 
157
  return array->buffer+(array->elements++ * array->size_of_element);
 
158
}
 
159
 
 
160
 
 
161
/*
 
162
  Pop last element from array.
 
163
 
 
164
  SYNOPSIS
 
165
    pop_dynamic()
 
166
      array
 
167
 
 
168
  RETURN VALUE
 
169
    pointer     Ok
 
170
    0           Array is empty
 
171
*/
 
172
 
 
173
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
 
174
{
 
175
  if (array->elements)
 
176
    return array->buffer+(--array->elements * array->size_of_element);
 
177
  return 0;
 
178
}
 
179
 
 
180
/*
 
181
  Replace element in array with given element and index
 
182
 
 
183
  SYNOPSIS
 
184
    set_dynamic()
 
185
      array
 
186
      element   Element to be inserted
 
187
      idx       Index where element is to be inserted
 
188
 
 
189
  DESCRIPTION
 
190
    set_dynamic() replaces element in array.
 
191
    If idx > max_element insert new element. Allocate memory if needed.
 
192
 
 
193
  RETURN VALUE
 
194
    true        Idx was out of range and allocation of new memory failed
 
195
    false       Ok
 
196
*/
 
197
 
 
198
bool set_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
 
199
{
 
200
  if (idx >= array->elements)
 
201
  {
 
202
    if (idx >= array->max_element && allocate_dynamic(array, idx))
 
203
      return true;
 
204
    memset(array->buffer+array->elements*array->size_of_element, 0,
 
205
           (idx - array->elements)*array->size_of_element);
 
206
    array->elements=idx+1;
 
207
  }
 
208
  memcpy(array->buffer+(idx * array->size_of_element),element,
 
209
         (size_t) array->size_of_element);
 
210
  return false;
 
211
}
 
212
 
 
213
 
 
214
/*
 
215
  Ensure that dynamic array has enough elements
 
216
 
 
217
  SYNOPSIS
 
218
    allocate_dynamic()
 
219
    array
 
220
    max_elements        Numbers of elements that is needed
 
221
 
 
222
  NOTES
 
223
   Any new allocated element are NOT initialized
 
224
 
 
225
  RETURN VALUE
 
226
    false       Ok
 
227
    true        Allocation of new memory failed
 
228
*/
 
229
 
 
230
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
 
231
{
 
232
  if (max_elements >= array->max_element)
 
233
  {
 
234
    uint32_t size;
 
235
    unsigned char *new_ptr;
 
236
    size= (max_elements + array->alloc_increment)/array->alloc_increment;
 
237
    size*= array->alloc_increment;
 
238
    if (array->buffer == (unsigned char *)(array + 1))
 
239
    {
 
240
       /*
 
241
         In this senerio, the buffer is statically preallocated,
 
242
         so we have to create an all-new malloc since we overflowed
 
243
       */
 
244
       if (!(new_ptr= (unsigned char *) malloc(size *
 
245
                                               array->size_of_element)))
 
246
         return 0;
 
247
       memcpy(new_ptr, array->buffer,
 
248
              array->elements * array->size_of_element);
 
249
     }
 
250
     else
 
251
 
 
252
 
 
253
    if (!(new_ptr=(unsigned char*) realloc(array->buffer,
 
254
                                        size* array->size_of_element)))
 
255
      return true;
 
256
    array->buffer= new_ptr;
 
257
    array->max_element= size;
 
258
  }
 
259
  return false;
 
260
}
 
261
 
 
262
 
 
263
/*
 
264
  Get an element from array by given index
 
265
 
 
266
  SYNOPSIS
 
267
    get_dynamic()
 
268
      array
 
269
      unsigned char*    Element to be returned. If idx > elements contain zeroes.
 
270
      idx       Index of element wanted.
 
271
*/
 
272
 
 
273
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
 
274
{
 
275
  if (idx >= array->elements)
 
276
  {
 
277
    memset(element, 0, array->size_of_element);
 
278
    return;
 
279
  }
 
280
  memcpy(element,array->buffer+idx*array->size_of_element,
 
281
         (size_t) array->size_of_element);
 
282
}
 
283
 
145
284
 
146
285
/*
147
286
  Empty array by freeing all memory
157
296
    Just mark as empty if we are using a static buffer
158
297
  */
159
298
  if (array->buffer == (unsigned char *)(array + 1))
160
 
    array->set_size(0);
 
299
    array->elements= 0;
161
300
  else
162
301
  if (array->buffer)
163
302
  {
164
303
    free(array->buffer);
165
304
    array->buffer=0;
166
 
    array->set_size(array->max_element=0);
 
305
    array->elements=array->max_element=0;
167
306
  }
168
307
}
169
308