dyn0dyn.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:7k
- /******************************************************
- The dynamically allocated array
- (c) 1996 Innobase Oy
- Created 2/5/1996 Heikki Tuuri
- *******************************************************/
- #define DYN_BLOCK_MAGIC_N 375767
- #define DYN_BLOCK_FULL_FLAG 0x1000000
- /****************************************************************
- Adds a new block to a dyn array. */
- 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);
- ut_ad(DYN_ARRAY_DATA_SIZE < DYN_BLOCK_FULL_FLAG);
- 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 */
- {
- 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_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 */
- byte* str, /* in: string to write */
- ulint len) /* in: string length */
- {
- byte* ptr;
- ulint n_copied;
- while (len > 0) {
- if (len > DYN_ARRAY_DATA_SIZE) {
- n_copied = DYN_ARRAY_DATA_SIZE;
- } else {
- n_copied = len;
- }
- ptr = (byte*) dyn_array_push(arr, n_copied);
- ut_memcpy(ptr, str, n_copied);
-
- str += n_copied;
- len -= n_copied;
- }
- }