📄 dyn0dyn.ic
字号:
/******************************************************The dynamically allocated array(c) 1996 Innobase OyCreated 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. */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_INLINEdyn_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_INLINEdyn_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_INLINEdyn_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_INLINEulintdyn_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_INLINEbyte*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_INLINEdyn_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_INLINEvoiddyn_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_INLINEvoid*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 usingdyn_array_close. */UNIV_INLINEbyte*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_INLINEvoiddyn_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_INLINEvoid*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_INLINEulintdyn_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_INLINEvoiddyn_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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -