~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/dyn0dyn.ic

  • Committer: Brian Aker
  • Date: 2009-12-08 23:37:35 UTC
  • mfrom: (1192.3.82 pandora-build)
  • mto: This revision was merged to the branch mainline in revision 1241.
  • Revision ID: brian@gaz-20091208233735-6zfhecyxizlw8bub
Merge range fix

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1996, 2009, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
13
 
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file include/dyn0dyn.ic
21
 
The dynamically allocated array
22
 
 
23
 
Created 2/5/1996 Heikki Tuuri
24
 
*******************************************************/
25
 
 
26
 
/** Value of dyn_block_struct::magic_n */
27
 
#define DYN_BLOCK_MAGIC_N       375767
28
 
/** Flag for dyn_block_struct::used that indicates a full block */
29
 
#define DYN_BLOCK_FULL_FLAG     0x1000000UL
30
 
 
31
 
/************************************************************//**
32
 
Adds a new block to a dyn array.
33
 
@return created block */
34
 
UNIV_INTERN
35
 
dyn_block_t*
36
 
dyn_array_add_block(
37
 
/*================*/
38
 
        dyn_array_t*    arr);   /*!< in: dyn array */
39
 
 
40
 
 
41
 
/************************************************************//**
42
 
Gets the first block in a dyn array. */
43
 
UNIV_INLINE
44
 
dyn_block_t*
45
 
dyn_array_get_first_block(
46
 
/*======================*/
47
 
        dyn_array_t*    arr)    /*!< in: dyn array */
48
 
{
49
 
        return(arr);
50
 
}
51
 
 
52
 
/************************************************************//**
53
 
Gets the last block in a dyn array. */
54
 
UNIV_INLINE
55
 
dyn_block_t*
56
 
dyn_array_get_last_block(
57
 
/*=====================*/
58
 
        dyn_array_t*    arr)    /*!< in: dyn array */
59
 
{
60
 
        if (arr->heap == NULL) {
61
 
 
62
 
                return(arr);
63
 
        }
64
 
 
65
 
        return(UT_LIST_GET_LAST(arr->base));
66
 
}
67
 
 
68
 
/********************************************************************//**
69
 
Gets the next block in a dyn array.
70
 
@return pointer to next, NULL if end of list */
71
 
UNIV_INLINE
72
 
dyn_block_t*
73
 
dyn_array_get_next_block(
74
 
/*=====================*/
75
 
        dyn_array_t*    arr,    /*!< in: dyn array */
76
 
        dyn_block_t*    block)  /*!< in: dyn array block */
77
 
{
78
 
        ut_ad(arr && block);
79
 
 
80
 
        if (arr->heap == NULL) {
81
 
                ut_ad(arr == block);
82
 
 
83
 
                return(NULL);
84
 
        }
85
 
 
86
 
        return(UT_LIST_GET_NEXT(list, block));
87
 
}
88
 
 
89
 
/********************************************************************//**
90
 
Gets the number of used bytes in a dyn array block.
91
 
@return number of bytes used */
92
 
UNIV_INLINE
93
 
ulint
94
 
dyn_block_get_used(
95
 
/*===============*/
96
 
        dyn_block_t*    block)  /*!< in: dyn array block */
97
 
{
98
 
        ut_ad(block);
99
 
 
100
 
        return((block->used) & ~DYN_BLOCK_FULL_FLAG);
101
 
}
102
 
 
103
 
/********************************************************************//**
104
 
Gets pointer to the start of data in a dyn array block.
105
 
@return pointer to data */
106
 
UNIV_INLINE
107
 
byte*
108
 
dyn_block_get_data(
109
 
/*===============*/
110
 
        dyn_block_t*    block)  /*!< in: dyn array block */
111
 
{
112
 
        ut_ad(block);
113
 
 
114
 
        return(block->data);
115
 
}
116
 
 
117
 
/*********************************************************************//**
118
 
Initializes a dynamic array.
119
 
@return initialized dyn array */
120
 
UNIV_INLINE
121
 
dyn_array_t*
122
 
dyn_array_create(
123
 
/*=============*/
124
 
        dyn_array_t*    arr)    /*!< in: pointer to a memory buffer of
125
 
                                size sizeof(dyn_array_t) */
126
 
{
127
 
        ut_ad(arr);
128
 
#if DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG
129
 
# error "DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG"
130
 
#endif
131
 
 
132
 
        arr->heap = NULL;
133
 
        arr->used = 0;
134
 
 
135
 
#ifdef UNIV_DEBUG
136
 
        arr->buf_end = 0;
137
 
        arr->magic_n = DYN_BLOCK_MAGIC_N;
138
 
#endif
139
 
        return(arr);
140
 
}
141
 
 
142
 
/************************************************************//**
143
 
Frees a dynamic array. */
144
 
UNIV_INLINE
145
 
void
146
 
dyn_array_free(
147
 
/*===========*/
148
 
        dyn_array_t*    arr)    /*!< in: dyn array */
149
 
{
150
 
        if (arr->heap != NULL) {
151
 
                mem_heap_free(arr->heap);
152
 
        }
153
 
 
154
 
#ifdef UNIV_DEBUG
155
 
        arr->magic_n = 0;
156
 
#endif
157
 
}
158
 
 
159
 
/*********************************************************************//**
160
 
Makes room on top of a dyn array and returns a pointer to the added element.
161
 
The caller must copy the element to the pointer returned.
162
 
@return pointer to the element */
163
 
UNIV_INLINE
164
 
void*
165
 
dyn_array_push(
166
 
/*===========*/
167
 
        dyn_array_t*    arr,    /*!< in: dynamic array */
168
 
        ulint           size)   /*!< in: size in bytes of the element */
169
 
{
170
 
        dyn_block_t*    block;
171
 
        ulint           used;
172
 
 
173
 
        ut_ad(arr);
174
 
        ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
175
 
        ut_ad(size <= DYN_ARRAY_DATA_SIZE);
176
 
        ut_ad(size);
177
 
 
178
 
        block = arr;
179
 
        used = block->used;
180
 
 
181
 
        if (used + size > DYN_ARRAY_DATA_SIZE) {
182
 
                /* Get the last array block */
183
 
 
184
 
                block = dyn_array_get_last_block(arr);
185
 
                used = block->used;
186
 
 
187
 
                if (used + size > DYN_ARRAY_DATA_SIZE) {
188
 
                        block = dyn_array_add_block(arr);
189
 
                        used = block->used;
190
 
                }
191
 
        }
192
 
 
193
 
        block->used = used + size;
194
 
        ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
195
 
 
196
 
        return((block->data) + used);
197
 
}
198
 
 
199
 
/*********************************************************************//**
200
 
Makes room on top of a dyn array and returns a pointer to a buffer in it.
201
 
After copying the elements, the caller must close the buffer using
202
 
dyn_array_close.
203
 
@return pointer to the buffer */
204
 
UNIV_INLINE
205
 
byte*
206
 
dyn_array_open(
207
 
/*===========*/
208
 
        dyn_array_t*    arr,    /*!< in: dynamic array */
209
 
        ulint           size)   /*!< in: size in bytes of the buffer; MUST be
210
 
                                smaller than DYN_ARRAY_DATA_SIZE! */
211
 
{
212
 
        dyn_block_t*    block;
213
 
        ulint           used;
214
 
 
215
 
        ut_ad(arr);
216
 
        ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
217
 
        ut_ad(size <= DYN_ARRAY_DATA_SIZE);
218
 
        ut_ad(size);
219
 
 
220
 
        block = arr;
221
 
        used = block->used;
222
 
 
223
 
        if (used + size > DYN_ARRAY_DATA_SIZE) {
224
 
                /* Get the last array block */
225
 
 
226
 
                block = dyn_array_get_last_block(arr);
227
 
                used = block->used;
228
 
 
229
 
                if (used + size > DYN_ARRAY_DATA_SIZE) {
230
 
                        block = dyn_array_add_block(arr);
231
 
                        used = block->used;
232
 
                        ut_a(size <= DYN_ARRAY_DATA_SIZE);
233
 
                }
234
 
        }
235
 
 
236
 
        ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
237
 
#ifdef UNIV_DEBUG
238
 
        ut_ad(arr->buf_end == 0);
239
 
 
240
 
        arr->buf_end = used + size;
241
 
#endif
242
 
        return((block->data) + used);
243
 
}
244
 
 
245
 
/*********************************************************************//**
246
 
Closes the buffer returned by dyn_array_open. */
247
 
UNIV_INLINE
248
 
void
249
 
dyn_array_close(
250
 
/*============*/
251
 
        dyn_array_t*    arr,    /*!< in: dynamic array */
252
 
        byte*           ptr)    /*!< in: buffer space from ptr up was not used */
253
 
{
254
 
        dyn_block_t*    block;
255
 
 
256
 
        ut_ad(arr);
257
 
        ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
258
 
 
259
 
        block = dyn_array_get_last_block(arr);
260
 
 
261
 
        ut_ad(arr->buf_end + block->data >= ptr);
262
 
 
263
 
        block->used = ptr - block->data;
264
 
 
265
 
        ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
266
 
 
267
 
#ifdef UNIV_DEBUG
268
 
        arr->buf_end = 0;
269
 
#endif
270
 
}
271
 
 
272
 
/************************************************************//**
273
 
Returns pointer to an element in dyn array.
274
 
@return pointer to element */
275
 
UNIV_INLINE
276
 
void*
277
 
dyn_array_get_element(
278
 
/*==================*/
279
 
        dyn_array_t*    arr,    /*!< in: dyn array */
280
 
        ulint           pos)    /*!< in: position of element as bytes
281
 
                                from array start */
282
 
{
283
 
        dyn_block_t*    block;
284
 
        ulint           used;
285
 
 
286
 
        ut_ad(arr);
287
 
        ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
288
 
 
289
 
        /* Get the first array block */
290
 
        block = dyn_array_get_first_block(arr);
291
 
 
292
 
        if (arr->heap != NULL) {
293
 
                used = dyn_block_get_used(block);
294
 
 
295
 
                while (pos >= used) {
296
 
                        pos -= used;
297
 
                        block = UT_LIST_GET_NEXT(list, block);
298
 
                        ut_ad(block);
299
 
 
300
 
                        used = dyn_block_get_used(block);
301
 
                }
302
 
        }
303
 
 
304
 
        ut_ad(block);
305
 
        ut_ad(dyn_block_get_used(block) >= pos);
306
 
 
307
 
        return(block->data + pos);
308
 
}
309
 
 
310
 
/************************************************************//**
311
 
Returns the size of stored data in a dyn array.
312
 
@return data size in bytes */
313
 
UNIV_INLINE
314
 
ulint
315
 
dyn_array_get_data_size(
316
 
/*====================*/
317
 
        dyn_array_t*    arr)    /*!< in: dyn array */
318
 
{
319
 
        dyn_block_t*    block;
320
 
        ulint           sum     = 0;
321
 
 
322
 
        ut_ad(arr);
323
 
        ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
324
 
 
325
 
        if (arr->heap == NULL) {
326
 
 
327
 
                return(arr->used);
328
 
        }
329
 
 
330
 
        /* Get the first array block */
331
 
        block = dyn_array_get_first_block(arr);
332
 
 
333
 
        while (block != NULL) {
334
 
                sum += dyn_block_get_used(block);
335
 
                block = dyn_array_get_next_block(arr, block);
336
 
        }
337
 
 
338
 
        return(sum);
339
 
}
340
 
 
341
 
/********************************************************//**
342
 
Pushes n bytes to a dyn array. */
343
 
UNIV_INLINE
344
 
void
345
 
dyn_push_string(
346
 
/*============*/
347
 
        dyn_array_t*    arr,    /*!< in: dyn array */
348
 
        const byte*     str,    /*!< in: string to write */
349
 
        ulint           len)    /*!< in: string length */
350
 
{
351
 
        ulint   n_copied;
352
 
 
353
 
        while (len > 0) {
354
 
                if (len > DYN_ARRAY_DATA_SIZE) {
355
 
                        n_copied = DYN_ARRAY_DATA_SIZE;
356
 
                } else {
357
 
                        n_copied = len;
358
 
                }
359
 
 
360
 
                memcpy(dyn_array_push(arr, n_copied), str, n_copied);
361
 
 
362
 
                str += n_copied;
363
 
                len -= n_copied;
364
 
        }
365
 
}