diff options
author | Sergei Golubchik <vuvova@gmail.com> | 2015-05-04 19:15:28 +0200 |
---|---|---|
committer | Sergei Golubchik <vuvova@gmail.com> | 2015-05-04 19:15:28 +0200 |
commit | 14a142fca67b9e1fb3f0250fda093f5b967f0138 (patch) | |
tree | dd49e0666c863d80b5c50642e36a9c945ea12b8a /storage/xtradb/include/dyn0dyn.ic | |
parent | dfb001edcd4b16bd4370b08b0176df78c4c5523f (diff) | |
download | mariadb-git-14a142fca67b9e1fb3f0250fda093f5b967f0138.tar.gz |
move to storage/xtradb
Diffstat (limited to 'storage/xtradb/include/dyn0dyn.ic')
-rw-r--r-- | storage/xtradb/include/dyn0dyn.ic | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/storage/xtradb/include/dyn0dyn.ic b/storage/xtradb/include/dyn0dyn.ic new file mode 100644 index 00000000000..0296554e2ee --- /dev/null +++ b/storage/xtradb/include/dyn0dyn.ic @@ -0,0 +1,306 @@ +/***************************************************************************** + +Copyright (c) 1996, 2013, Oracle and/or its affiliates. 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., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/dyn0dyn.ic +The dynamically allocated array + +Created 2/5/1996 Heikki Tuuri +*******************************************************/ + +/** Value of dyn_block_t::magic_n */ +#define DYN_BLOCK_MAGIC_N 375767 +/** Flag for dyn_block_t::used that indicates a full block */ +#define DYN_BLOCK_FULL_FLAG 0x1000000UL + +/************************************************************//** +Adds a new block to a dyn array. +@return created block */ +UNIV_INTERN +dyn_block_t* +dyn_array_add_block( +/*================*/ + dyn_array_t* arr) /*!< in/out: dyn array */ + __attribute__((nonnull, warn_unused_result)); + +/********************************************************************//** +Gets the number of used bytes in a dyn array block. +@return number of bytes used */ +UNIV_INLINE +ulint +dyn_block_get_used( +/*===============*/ + const 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. +@return pointer to data */ +UNIV_INLINE +byte* +dyn_block_get_data( +/*===============*/ + const dyn_block_t* block) /*!< in: dyn array block */ +{ + ut_ad(block); + + return(const_cast<byte*>(block->data)); +} + +/*********************************************************************//** +Initializes a dynamic array. +@return initialized dyn array */ +UNIV_INLINE +dyn_array_t* +dyn_array_create( +/*=============*/ + dyn_array_t* arr) /*!< in/out: 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; + + ut_d(arr->buf_end = 0); + ut_d(arr->magic_n = DYN_BLOCK_MAGIC_N); + + 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); + } + + ut_d(arr->magic_n = 0); +} + +/*********************************************************************//** +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. +@return pointer to the element */ +UNIV_INLINE +void* +dyn_array_push( +/*===========*/ + dyn_array_t* arr, /*!< in/out: 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; + + if (block->used + size > DYN_ARRAY_DATA_SIZE) { + /* Get the last array block */ + + block = dyn_array_get_last_block(arr); + + if (block->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. +@return pointer to the buffer */ +UNIV_INLINE +byte* +dyn_array_open( +/*===========*/ + 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; + + ut_ad(arr); + ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); + ut_ad(size <= DYN_ARRAY_DATA_SIZE); + ut_ad(size); + + block = arr; + + if (block->used + size > DYN_ARRAY_DATA_SIZE) { + /* Get the last array block */ + + block = dyn_array_get_last_block(arr); + + if (block->used + size > DYN_ARRAY_DATA_SIZE) { + block = dyn_array_add_block(arr); + ut_a(size <= DYN_ARRAY_DATA_SIZE); + } + } + + ut_ad(block->used <= DYN_ARRAY_DATA_SIZE); + ut_ad(arr->buf_end == 0); + ut_d(arr->buf_end = block->used + size); + + return(block->data + block->used); +} + +/*********************************************************************//** +Closes the buffer returned by dyn_array_open. */ +UNIV_INLINE +void +dyn_array_close( +/*============*/ + dyn_array_t* arr, /*!< in/out: dynamic array */ + const byte* ptr) /*!< in: end of used space */ +{ + 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); + + ut_d(arr->buf_end = 0); +} + +/************************************************************//** +Returns pointer to an element in dyn array. +@return pointer to element */ +UNIV_INLINE +void* +dyn_array_get_element( +/*==================*/ + const dyn_array_t* arr, /*!< in: dyn array */ + ulint pos) /*!< in: position of element + in bytes from array start */ +{ + const dyn_block_t* block; + + 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) { + for (;;) { + ulint used = dyn_block_get_used(block); + + if (pos < used) { + break; + } + + pos -= used; + block = UT_LIST_GET_NEXT(list, block); + ut_ad(block); + } + } + + ut_ad(block); + ut_ad(dyn_block_get_used(block) >= pos); + + return(const_cast<byte*>(block->data) + pos); +} + +/************************************************************//** +Returns the size of stored data in a dyn array. +@return data size in bytes */ +UNIV_INLINE +ulint +dyn_array_get_data_size( +/*====================*/ + const dyn_array_t* arr) /*!< in: dyn array */ +{ + const 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/out: 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; + } +} |