diff options
author | unknown <knielsen@knielsen-hq.org> | 2009-06-09 13:16:11 +0200 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2009-06-09 13:16:11 +0200 |
commit | 47b9a0b53098541978a915584e00c8af0904b6cd (patch) | |
tree | d7e62c1af5118cd3ec9346de436569e907fcc51d /storage/xtradb/include/dyn0dyn.ic | |
parent | 8eee7808207342081c56f5db5deaed9077f73433 (diff) | |
parent | 107072563d771422c9bbb9aeeedce8ae19c5b838 (diff) | |
download | mariadb-git-47b9a0b53098541978a915584e00c8af0904b6cd.tar.gz |
Import Percona XtraDB into the MariaDB source tree.
Diffstat (limited to 'storage/xtradb/include/dyn0dyn.ic')
-rw-r--r-- | storage/xtradb/include/dyn0dyn.ic | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/storage/xtradb/include/dyn0dyn.ic b/storage/xtradb/include/dyn0dyn.ic new file mode 100644 index 00000000000..1ef8b284a99 --- /dev/null +++ b/storage/xtradb/include/dyn0dyn.ic @@ -0,0 +1,362 @@ +/***************************************************************************** + +Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/****************************************************** +The dynamically allocated array + +Created 2/5/1996 Heikki Tuuri +*******************************************************/ + +#define DYN_BLOCK_MAGIC_N 375767 +#define DYN_BLOCK_FULL_FLAG 0x1000000UL + +/**************************************************************** +Adds a new block to a dyn array. */ +UNIV_INTERN +dyn_block_t* +dyn_array_add_block( +/*================*/ + /* out: created block */ + dyn_array_t* arr); /* in: dyn array */ + + +/**************************************************************** +Gets the first block in a dyn array. */ +UNIV_INLINE +dyn_block_t* +dyn_array_get_first_block( +/*======================*/ + dyn_array_t* arr) /* in: dyn array */ +{ + return(arr); +} + +/**************************************************************** +Gets the last block in a dyn array. */ +UNIV_INLINE +dyn_block_t* +dyn_array_get_last_block( +/*=====================*/ + dyn_array_t* arr) /* in: dyn array */ +{ + if (arr->heap == NULL) { + + return(arr); + } + + return(UT_LIST_GET_LAST(arr->base)); +} + +/************************************************************************ +Gets the next block in a dyn array. */ +UNIV_INLINE +dyn_block_t* +dyn_array_get_next_block( +/*=====================*/ + /* out: pointer to next, NULL if end of list */ + dyn_array_t* arr, /* in: dyn array */ + dyn_block_t* block) /* in: dyn array block */ +{ + ut_ad(arr && block); + + if (arr->heap == NULL) { + ut_ad(arr == block); + + return(NULL); + } + + return(UT_LIST_GET_NEXT(list, block)); +} + +/************************************************************************ +Gets the number of used bytes in a dyn array block. */ +UNIV_INLINE +ulint +dyn_block_get_used( +/*===============*/ + /* out: number of bytes used */ + dyn_block_t* block) /* in: dyn array block */ +{ + ut_ad(block); + + return((block->used) & ~DYN_BLOCK_FULL_FLAG); +} + +/************************************************************************ +Gets pointer to the start of data in a dyn array block. */ +UNIV_INLINE +byte* +dyn_block_get_data( +/*===============*/ + /* out: pointer to data */ + dyn_block_t* block) /* in: dyn array block */ +{ + ut_ad(block); + + return(block->data); +} + +/************************************************************************* +Initializes a dynamic array. */ +UNIV_INLINE +dyn_array_t* +dyn_array_create( +/*=============*/ + /* out: initialized dyn array */ + dyn_array_t* arr) /* in: pointer to a memory buffer of + size sizeof(dyn_array_t) */ +{ + ut_ad(arr); +#if DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG +# error "DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG" +#endif + + arr->heap = NULL; + arr->used = 0; + +#ifdef UNIV_DEBUG + arr->buf_end = 0; + arr->magic_n = DYN_BLOCK_MAGIC_N; +#endif + return(arr); +} + +/**************************************************************** +Frees a dynamic array. */ +UNIV_INLINE +void +dyn_array_free( +/*===========*/ + dyn_array_t* arr) /* in: dyn array */ +{ + if (arr->heap != NULL) { + mem_heap_free(arr->heap); + } + +#ifdef UNIV_DEBUG + arr->magic_n = 0; +#endif +} + +/************************************************************************* +Makes room on top of a dyn array and returns a pointer to the added element. +The caller must copy the element to the pointer returned. */ +UNIV_INLINE +void* +dyn_array_push( +/*===========*/ + /* out: pointer to the element */ + dyn_array_t* arr, /* in: dynamic array */ + ulint size) /* in: size in bytes of the element */ +{ + dyn_block_t* block; + ulint used; + + ut_ad(arr); + ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); + ut_ad(size <= DYN_ARRAY_DATA_SIZE); + ut_ad(size); + + block = arr; + used = block->used; + + if (used + size > DYN_ARRAY_DATA_SIZE) { + /* Get the last array block */ + + block = dyn_array_get_last_block(arr); + used = block->used; + + if (used + size > DYN_ARRAY_DATA_SIZE) { + block = dyn_array_add_block(arr); + used = block->used; + } + } + + block->used = used + size; + ut_ad(block->used <= DYN_ARRAY_DATA_SIZE); + + return((block->data) + used); +} + +/************************************************************************* +Makes room on top of a dyn array and returns a pointer to a buffer in it. +After copying the elements, the caller must close the buffer using +dyn_array_close. */ +UNIV_INLINE +byte* +dyn_array_open( +/*===========*/ + /* out: pointer to the buffer */ + dyn_array_t* arr, /* in: dynamic array */ + ulint size) /* in: size in bytes of the buffer; MUST be + smaller than DYN_ARRAY_DATA_SIZE! */ +{ + dyn_block_t* block; + ulint used; + + ut_ad(arr); + ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); + ut_ad(size <= DYN_ARRAY_DATA_SIZE); + ut_ad(size); + + block = arr; + used = block->used; + + if (used + size > DYN_ARRAY_DATA_SIZE) { + /* Get the last array block */ + + block = dyn_array_get_last_block(arr); + used = block->used; + + if (used + size > DYN_ARRAY_DATA_SIZE) { + block = dyn_array_add_block(arr); + used = block->used; + ut_a(size <= DYN_ARRAY_DATA_SIZE); + } + } + + ut_ad(block->used <= DYN_ARRAY_DATA_SIZE); +#ifdef UNIV_DEBUG + ut_ad(arr->buf_end == 0); + + arr->buf_end = used + size; +#endif + return((block->data) + used); +} + +/************************************************************************* +Closes the buffer returned by dyn_array_open. */ +UNIV_INLINE +void +dyn_array_close( +/*============*/ + dyn_array_t* arr, /* in: dynamic array */ + byte* ptr) /* in: buffer space from ptr up was not used */ +{ + dyn_block_t* block; + + ut_ad(arr); + ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); + + block = dyn_array_get_last_block(arr); + + ut_ad(arr->buf_end + block->data >= ptr); + + block->used = ptr - block->data; + + ut_ad(block->used <= DYN_ARRAY_DATA_SIZE); + +#ifdef UNIV_DEBUG + arr->buf_end = 0; +#endif +} + +/**************************************************************** +Returns pointer to an element in dyn array. */ +UNIV_INLINE +void* +dyn_array_get_element( +/*==================*/ + /* out: pointer to element */ + dyn_array_t* arr, /* in: dyn array */ + ulint pos) /* in: position of element as bytes + from array start */ +{ + dyn_block_t* block; + ulint used; + + ut_ad(arr); + ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); + + /* Get the first array block */ + block = dyn_array_get_first_block(arr); + + if (arr->heap != NULL) { + used = dyn_block_get_used(block); + + while (pos >= used) { + pos -= used; + block = UT_LIST_GET_NEXT(list, block); + ut_ad(block); + + used = dyn_block_get_used(block); + } + } + + ut_ad(block); + ut_ad(dyn_block_get_used(block) >= pos); + + return(block->data + pos); +} + +/**************************************************************** +Returns the size of stored data in a dyn array. */ +UNIV_INLINE +ulint +dyn_array_get_data_size( +/*====================*/ + /* out: data size in bytes */ + dyn_array_t* arr) /* in: dyn array */ +{ + dyn_block_t* block; + ulint sum = 0; + + ut_ad(arr); + ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); + + if (arr->heap == NULL) { + + return(arr->used); + } + + /* Get the first array block */ + block = dyn_array_get_first_block(arr); + + while (block != NULL) { + sum += dyn_block_get_used(block); + block = dyn_array_get_next_block(arr, block); + } + + return(sum); +} + +/************************************************************ +Pushes n bytes to a dyn array. */ +UNIV_INLINE +void +dyn_push_string( +/*============*/ + dyn_array_t* arr, /* in: dyn array */ + const byte* str, /* in: string to write */ + ulint len) /* in: string length */ +{ + ulint n_copied; + + while (len > 0) { + if (len > DYN_ARRAY_DATA_SIZE) { + n_copied = DYN_ARRAY_DATA_SIZE; + } else { + n_copied = len; + } + + memcpy(dyn_array_push(arr, n_copied), str, n_copied); + + str += n_copied; + len -= n_copied; + } +} |