dyn0dyn.ic
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. The dynamically allocated array
  3. (c) 1996 Innobase Oy
  4. Created 2/5/1996 Heikki Tuuri
  5. *******************************************************/
  6. #define DYN_BLOCK_MAGIC_N 375767
  7. #define DYN_BLOCK_FULL_FLAG 0x1000000UL
  8. /****************************************************************
  9. Adds a new block to a dyn array. */
  10. dyn_block_t*
  11. dyn_array_add_block(
  12. /*================*/
  13. /* out: created block */
  14. dyn_array_t* arr); /* in: dyn array */
  15. /****************************************************************
  16. Gets the first block in a dyn array. */
  17. UNIV_INLINE
  18. dyn_block_t*
  19. dyn_array_get_first_block(
  20. /*======================*/
  21. dyn_array_t* arr) /* in: dyn array */
  22. {
  23. return(arr);
  24. }
  25. /****************************************************************
  26. Gets the last block in a dyn array. */
  27. UNIV_INLINE
  28. dyn_block_t*
  29. dyn_array_get_last_block(
  30. /*=====================*/
  31. dyn_array_t* arr) /* in: dyn array */
  32. {
  33. if (arr->heap == NULL) {
  34. return(arr);
  35. }  
  36. return(UT_LIST_GET_LAST(arr->base));
  37. }
  38. /************************************************************************
  39. Gets the next block in a dyn array. */
  40. UNIV_INLINE
  41. dyn_block_t*
  42. dyn_array_get_next_block(
  43. /*=====================*/
  44. /* out: pointer to next, NULL if end of list */
  45. dyn_array_t* arr, /* in: dyn array */
  46. dyn_block_t* block) /* in: dyn array block */
  47. {
  48. ut_ad(arr && block);
  49. if (arr->heap == NULL) {
  50. ut_ad(arr == block);
  51. return(NULL);
  52. }
  53. return(UT_LIST_GET_NEXT(list, block));
  54. }
  55. /************************************************************************
  56. Gets the number of used bytes in a dyn array block. */
  57. UNIV_INLINE
  58. ulint
  59. dyn_block_get_used(
  60. /*===============*/
  61. /* out: number of bytes used */
  62. dyn_block_t* block) /* in: dyn array block */
  63. {
  64. ut_ad(block);
  65. return((block->used) & ~DYN_BLOCK_FULL_FLAG);
  66. }
  67. /************************************************************************
  68. Gets pointer to the start of data in a dyn array block. */
  69. UNIV_INLINE
  70. byte*
  71. dyn_block_get_data(
  72. /*===============*/
  73. /* out: pointer to data */
  74. dyn_block_t* block) /* in: dyn array block */
  75. {
  76. ut_ad(block);
  77. return(block->data);
  78. }
  79. /*************************************************************************
  80. Initializes a dynamic array. */
  81. UNIV_INLINE
  82. dyn_array_t*
  83. dyn_array_create(
  84. /*=============*/
  85. /* out: initialized dyn array */
  86. dyn_array_t* arr) /* in: pointer to a memory buffer of
  87. size sizeof(dyn_array_t) */
  88. {
  89. ut_ad(arr);
  90. ut_ad(DYN_ARRAY_DATA_SIZE < DYN_BLOCK_FULL_FLAG);
  91. arr->heap = NULL;
  92. arr->used = 0;
  93. #ifdef UNIV_DEBUG
  94. arr->buf_end = 0;
  95. arr->magic_n = DYN_BLOCK_MAGIC_N;
  96. #endif
  97. return(arr);
  98. }
  99. /****************************************************************
  100. Frees a dynamic array. */
  101. UNIV_INLINE
  102. void
  103. dyn_array_free(
  104. /*===========*/
  105. dyn_array_t* arr) /* in: dyn array */
  106. {
  107. if (arr->heap != NULL) {
  108. mem_heap_free(arr->heap);
  109. }
  110. #ifdef UNIV_DEBUG
  111. arr->magic_n = 0;
  112. #endif
  113. }
  114. /*************************************************************************
  115. Makes room on top of a dyn array and returns a pointer to the added element.
  116. The caller must copy the element to the pointer returned. */
  117. UNIV_INLINE
  118. void*
  119. dyn_array_push(
  120. /*===========*/
  121. /* out: pointer to the element */
  122. dyn_array_t* arr, /* in: dynamic array */
  123. ulint size) /* in: size in bytes of the element */
  124. {
  125. dyn_block_t* block;
  126. ulint used;
  127. ut_ad(arr);
  128. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  129. ut_ad(size <= DYN_ARRAY_DATA_SIZE);
  130. ut_ad(size);
  131. block = arr;
  132. used = block->used;
  133. if (used + size > DYN_ARRAY_DATA_SIZE) {
  134. /* Get the last array block */
  135. block = dyn_array_get_last_block(arr);
  136. used = block->used;
  137. if (used + size > DYN_ARRAY_DATA_SIZE) {
  138. block = dyn_array_add_block(arr);
  139. used = block->used;
  140. }
  141. }
  142. block->used = used + size;
  143. ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
  144. return((block->data) + used);
  145. }
  146. /*************************************************************************
  147. Makes room on top of a dyn array and returns a pointer to a buffer in it.
  148. After copying the elements, the caller must close the buffer using
  149. dyn_array_close. */
  150. UNIV_INLINE
  151. byte*
  152. dyn_array_open(
  153. /*===========*/
  154. /* out: pointer to the buffer */
  155. dyn_array_t* arr, /* in: dynamic array */
  156. ulint size) /* in: size in bytes of the buffer; MUST be
  157. smaller than DYN_ARRAY_DATA_SIZE! */
  158. {
  159. dyn_block_t* block;
  160. ulint used;
  161. ut_ad(arr);
  162. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  163. ut_ad(size <= DYN_ARRAY_DATA_SIZE);
  164. ut_ad(size);
  165. block = arr;
  166. used = block->used;
  167. if (used + size > DYN_ARRAY_DATA_SIZE) {
  168. /* Get the last array block */
  169. block = dyn_array_get_last_block(arr);
  170. used = block->used;
  171. if (used + size > DYN_ARRAY_DATA_SIZE) {
  172. block = dyn_array_add_block(arr);
  173. used = block->used;
  174. ut_a(size <= DYN_ARRAY_DATA_SIZE);
  175. }
  176. }
  177. ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
  178. #ifdef UNIV_DEBUG
  179. ut_ad(arr->buf_end == 0);
  180. arr->buf_end = used + size;
  181. #endif
  182. return((block->data) + used);
  183. }
  184. /*************************************************************************
  185. Closes the buffer returned by dyn_array_open. */
  186. UNIV_INLINE
  187. void
  188. dyn_array_close(
  189. /*============*/
  190. dyn_array_t* arr, /* in: dynamic array */
  191. byte* ptr) /* in: buffer space from ptr up was not used */
  192. {
  193. dyn_block_t* block;
  194. ut_ad(arr);
  195. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  196. block = dyn_array_get_last_block(arr);
  197. ut_ad(arr->buf_end + block->data >= ptr);
  198. block->used = ptr - block->data;
  199. ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
  200. #ifdef UNIV_DEBUG
  201. arr->buf_end = 0;
  202. #endif
  203. }
  204. /****************************************************************
  205. Returns pointer to an element in dyn array. */
  206. UNIV_INLINE
  207. void*
  208. dyn_array_get_element(
  209. /*==================*/
  210. /* out: pointer to element */
  211. dyn_array_t* arr, /* in: dyn array */
  212. ulint pos) /* in: position of element as bytes 
  213. from array start */
  214. {
  215. dyn_block_t* block;
  216. ulint used;
  217. ut_ad(arr);
  218. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  219. /* Get the first array block */
  220. block = dyn_array_get_first_block(arr);
  221. if (arr->heap != NULL) {
  222. used = dyn_block_get_used(block);
  223. while (pos >= used) {
  224. pos -= used;
  225. block = UT_LIST_GET_NEXT(list, block);
  226. ut_ad(block);
  227. used = dyn_block_get_used(block);
  228. }
  229. }
  230. ut_ad(block);
  231. ut_ad(dyn_block_get_used(block) >= pos);
  232. return(block->data + pos);
  233. }
  234. /****************************************************************
  235. Returns the size of stored data in a dyn array. */
  236. UNIV_INLINE
  237. ulint
  238. dyn_array_get_data_size(
  239. /*====================*/
  240. /* out: data size in bytes */
  241. dyn_array_t* arr) /* in: dyn array */
  242. {
  243. dyn_block_t* block;
  244. ulint sum  = 0;
  245. ut_ad(arr);
  246. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  247. if (arr->heap == NULL) {
  248. return(arr->used);
  249. }
  250. /* Get the first array block */
  251. block = dyn_array_get_first_block(arr);
  252. while (block != NULL) {
  253. sum += dyn_block_get_used(block);
  254. block = dyn_array_get_next_block(arr, block);
  255. }
  256. return(sum);
  257. }
  258. /************************************************************
  259. Pushes n bytes to a dyn array. */
  260. UNIV_INLINE
  261. void
  262. dyn_push_string(
  263. /*============*/
  264. dyn_array_t* arr, /* in: dyn array */
  265. byte* str, /* in: string to write */
  266. ulint len) /* in: string length */
  267. {
  268. byte* ptr;
  269. ulint n_copied;
  270. while (len > 0) {
  271. if (len > DYN_ARRAY_DATA_SIZE) {
  272. n_copied = DYN_ARRAY_DATA_SIZE;
  273. } else {
  274. n_copied = len;
  275. }
  276. ptr = (byte*) dyn_array_push(arr, n_copied);
  277. ut_memcpy(ptr, str, n_copied);
  278. str += n_copied;
  279. len -= n_copied;
  280. }
  281. }