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