~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/include/dyn0dyn.ic

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 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
}