~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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
/* Handling of arrays that can grow dynamicly. */
17
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
18
#include <config.h>
19
#include <drizzled/internal/my_sys.h>
20
#include <drizzled/internal/m_string.h>
1 by brian
clean slate
21
1067.4.10 by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max.
22
#include <algorithm>
23
24
using namespace std;
25
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
26
namespace drizzled
27
{
28
1165.1.138 by Stewart Smith
make allocate_dynamic() static to mysys/dynamic_array.cc
29
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements);
30
1 by brian
clean slate
31
/*
32
  Initiate dynamic array
33
34
  SYNOPSIS
35
    init_dynamic_array2()
36
      array		Pointer to an array
37
      element_size	Size of element
38
      init_buffer       Initial buffer pointer
39
      init_alloc	Number of initial elements
40
      alloc_increment	Increment for adding new elements
41
42
  DESCRIPTION
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
43
    init_dynamic_array() initiates array and allocate space for
44
    init_alloc eilements.
1 by brian
clean slate
45
    Array is usable even if space allocation failed.
46
    Static buffers must begin immediately after the array structure.
47
48
  RETURN VALUE
656.3.2 by Monty Taylor
Removed my_nosys and my_quick. /me shudders.
49
    true	malloc() failed
163 by Brian Aker
Merge Monty's code.
50
    false	Ok
1 by brian
clean slate
51
*/
52
482 by Brian Aker
Remove uint.
53
bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint32_t element_size,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
54
                            void *init_buffer, uint32_t init_alloc,
575.1.6 by Monty Taylor
Cleaned up some headers for PCH.
55
                            uint32_t alloc_increment)
1 by brian
clean slate
56
{
57
  if (!alloc_increment)
58
  {
1067.4.10 by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max.
59
    alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16U);
1 by brian
clean slate
60
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
61
      alloc_increment=init_alloc*2;
62
  }
63
64
  if (!init_alloc)
65
  {
66
    init_alloc=alloc_increment;
67
    init_buffer= 0;
68
  }
69
  array->elements=0;
70
  array->max_element=init_alloc;
71
  array->alloc_increment=alloc_increment;
72
  array->size_of_element=element_size;
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
73
  if ((array->buffer= (unsigned char*) init_buffer))
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
74
    return(false);
656.3.2 by Monty Taylor
Removed my_nosys and my_quick. /me shudders.
75
  if (!(array->buffer=(unsigned char*) malloc(element_size*init_alloc)))
1 by brian
clean slate
76
  {
77
    array->max_element=0;
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
78
    return(true);
1 by brian
clean slate
79
  }
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
80
  return(false);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
81
}
1 by brian
clean slate
82
83
/*
84
  Insert element at the end of array. Allocate memory if needed.
85
86
  SYNOPSIS
87
    insert_dynamic()
88
      array
89
      element
90
91
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
92
    true	Insert failed
93
    false	Ok
1 by brian
clean slate
94
*/
95
481 by Brian Aker
Remove all of uchar.
96
bool insert_dynamic(DYNAMIC_ARRAY *array, unsigned char* element)
1 by brian
clean slate
97
{
481 by Brian Aker
Remove all of uchar.
98
  unsigned char* buffer;
1 by brian
clean slate
99
  if (array->elements == array->max_element)
100
  {						/* Call only when nessesary */
101
    if (!(buffer=alloc_dynamic(array)))
163 by Brian Aker
Merge Monty's code.
102
      return true;
1 by brian
clean slate
103
  }
104
  else
105
  {
106
    buffer=array->buffer+(array->elements * array->size_of_element);
107
    array->elements++;
108
  }
109
  memcpy(buffer,element,(size_t) array->size_of_element);
163 by Brian Aker
Merge Monty's code.
110
  return false;
1 by brian
clean slate
111
}
112
113
114
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
115
  Alloc space for next element(s)
1 by brian
clean slate
116
117
  SYNOPSIS
118
    alloc_dynamic()
119
      array
120
121
  DESCRIPTION
122
    alloc_dynamic() checks if there is empty space for at least
123
    one element if not tries to allocate space for alloc_increment
124
    elements at the end of array.
125
126
  RETURN VALUE
127
    pointer	Pointer to empty space for element
128
    0		Error
129
*/
130
481 by Brian Aker
Remove all of uchar.
131
unsigned char *alloc_dynamic(DYNAMIC_ARRAY *array)
1 by brian
clean slate
132
{
133
  if (array->elements == array->max_element)
134
  {
135
    char *new_ptr;
481 by Brian Aker
Remove all of uchar.
136
    if (array->buffer == (unsigned char *)(array + 1))
1 by brian
clean slate
137
    {
138
      /*
139
        In this senerio, the buffer is statically preallocated,
140
        so we have to create an all-new malloc since we overflowed
141
      */
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
142
      if (!(new_ptr= (char *) malloc((array->max_element+
143
                                     array->alloc_increment) *
144
                                     array->size_of_element)))
1 by brian
clean slate
145
        return 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
146
      memcpy(new_ptr, array->buffer,
1 by brian
clean slate
147
             array->elements * array->size_of_element);
148
    }
656.1.47 by Monty Taylor
More malloc return check fixes.
149
    else if (!(new_ptr= (char*) realloc(array->buffer,
150
                                        (array->max_element+
151
                                         array->alloc_increment)*
152
                                        array->size_of_element)))
1 by brian
clean slate
153
      return 0;
481 by Brian Aker
Remove all of uchar.
154
    array->buffer= (unsigned char*) new_ptr;
1 by brian
clean slate
155
    array->max_element+=array->alloc_increment;
156
  }
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
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
167
168
  RETURN VALUE
1 by brian
clean slate
169
    pointer	Ok
170
    0		Array is empty
171
*/
172
481 by Brian Aker
Remove all of uchar.
173
unsigned char *pop_dynamic(DYNAMIC_ARRAY *array)
1 by brian
clean slate
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
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
190
    set_dynamic() replaces element in array.
191
    If idx > max_element insert new element. Allocate memory if needed.
192
1 by brian
clean slate
193
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
194
    true	Idx was out of range and allocation of new memory failed
195
    false	Ok
1 by brian
clean slate
196
*/
197
482 by Brian Aker
Remove uint.
198
bool set_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
1 by brian
clean slate
199
{
200
  if (idx >= array->elements)
201
  {
202
    if (idx >= array->max_element && allocate_dynamic(array, idx))
163 by Brian Aker
Merge Monty's code.
203
      return true;
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
204
    memset(array->buffer+array->elements*array->size_of_element, 0,
205
           (idx - array->elements)*array->size_of_element);
1 by brian
clean slate
206
    array->elements=idx+1;
207
  }
208
  memcpy(array->buffer+(idx * array->size_of_element),element,
209
	 (size_t) array->size_of_element);
163 by Brian Aker
Merge Monty's code.
210
  return false;
1 by brian
clean slate
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
163 by Brian Aker
Merge Monty's code.
226
    false	Ok
227
    true	Allocation of new memory failed
1 by brian
clean slate
228
*/
229
1165.1.138 by Stewart Smith
make allocate_dynamic() static to mysys/dynamic_array.cc
230
static bool allocate_dynamic(DYNAMIC_ARRAY *array, uint32_t max_elements)
1 by brian
clean slate
231
{
232
  if (max_elements >= array->max_element)
233
  {
482 by Brian Aker
Remove uint.
234
    uint32_t size;
481 by Brian Aker
Remove all of uchar.
235
    unsigned char *new_ptr;
1 by brian
clean slate
236
    size= (max_elements + array->alloc_increment)/array->alloc_increment;
237
    size*= array->alloc_increment;
481 by Brian Aker
Remove all of uchar.
238
    if (array->buffer == (unsigned char *)(array + 1))
1 by brian
clean slate
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
       */
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
244
       if (!(new_ptr= (unsigned char *) malloc(size *
245
                                               array->size_of_element)))
1 by brian
clean slate
246
         return 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
247
       memcpy(new_ptr, array->buffer,
1 by brian
clean slate
248
              array->elements * array->size_of_element);
249
     }
250
     else
251
252
656.1.47 by Monty Taylor
More malloc return check fixes.
253
    if (!(new_ptr=(unsigned char*) realloc(array->buffer,
254
                                        size* array->size_of_element)))
163 by Brian Aker
Merge Monty's code.
255
      return true;
1 by brian
clean slate
256
    array->buffer= new_ptr;
257
    array->max_element= size;
258
  }
163 by Brian Aker
Merge Monty's code.
259
  return false;
1 by brian
clean slate
260
}
261
262
263
/*
264
  Get an element from array by given index
265
266
  SYNOPSIS
267
    get_dynamic()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
268
      array
481 by Brian Aker
Remove all of uchar.
269
      unsigned char*	Element to be returned. If idx > elements contain zeroes.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
270
      idx	Index of element wanted.
1 by brian
clean slate
271
*/
272
482 by Brian Aker
Remove uint.
273
void get_dynamic(DYNAMIC_ARRAY *array, unsigned char* element, uint32_t idx)
1 by brian
clean slate
274
{
275
  if (idx >= array->elements)
276
  {
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
277
    memset(element, 0, array->size_of_element);
1 by brian
clean slate
278
    return;
279
  }
280
  memcpy(element,array->buffer+idx*array->size_of_element,
281
         (size_t) array->size_of_element);
282
}
283
284
285
/*
286
  Empty array by freeing all memory
287
288
  SYNOPSIS
289
    delete_dynamic()
290
      array	Array to be deleted
291
*/
292
293
void delete_dynamic(DYNAMIC_ARRAY *array)
294
{
295
  /*
296
    Just mark as empty if we are using a static buffer
297
  */
481 by Brian Aker
Remove all of uchar.
298
  if (array->buffer == (unsigned char *)(array + 1))
1 by brian
clean slate
299
    array->elements= 0;
300
  else
301
  if (array->buffer)
302
  {
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.
303
    free(array->buffer);
1 by brian
clean slate
304
    array->buffer=0;
305
    array->elements=array->max_element=0;
306
  }
307
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
308
309
} /* namespace drizzled */