dyn0dyn.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小: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 0x1000000
  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 */
  157. {
  158. dyn_block_t* block;
  159. ulint used;
  160. ut_ad(arr);
  161. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  162. ut_ad(size <= DYN_ARRAY_DATA_SIZE);
  163. ut_ad(size);
  164. block = arr;
  165. used = block->used;
  166. if (used + size > DYN_ARRAY_DATA_SIZE) {
  167. /* Get the last array block */
  168. block = dyn_array_get_last_block(arr);
  169. used = block->used;
  170. if (used + size > DYN_ARRAY_DATA_SIZE) {
  171. block = dyn_array_add_block(arr);
  172. used = block->used;
  173. }
  174. }
  175. ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
  176. #ifdef UNIV_DEBUG
  177. ut_ad(arr->buf_end == 0);
  178. arr->buf_end = used + size;
  179. #endif
  180. return((block->data) + used);
  181. }
  182. /*************************************************************************
  183. Closes the buffer returned by dyn_array_open. */
  184. UNIV_INLINE
  185. void
  186. dyn_array_close(
  187. /*============*/
  188. dyn_array_t* arr, /* in: dynamic array */
  189. byte* ptr) /* in: buffer space from ptr up was not used */
  190. {
  191. dyn_block_t* block;
  192. ut_ad(arr);
  193. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  194. block = dyn_array_get_last_block(arr);
  195. ut_ad(arr->buf_end + block->data >= ptr);
  196. block->used = ptr - block->data;
  197. ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
  198. #ifdef UNIV_DEBUG
  199. arr->buf_end = 0;
  200. #endif
  201. }
  202. /****************************************************************
  203. Returns pointer to an element in dyn array. */
  204. UNIV_INLINE
  205. void*
  206. dyn_array_get_element(
  207. /*==================*/
  208. /* out: pointer to element */
  209. dyn_array_t* arr, /* in: dyn array */
  210. ulint pos) /* in: position of element as bytes 
  211. from array start */
  212. {
  213. dyn_block_t* block;
  214. ulint used;
  215. ut_ad(arr);
  216. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  217. /* Get the first array block */
  218. block = dyn_array_get_first_block(arr);
  219. if (arr->heap != NULL) {
  220. used = dyn_block_get_used(block);
  221. while (pos >= used) {
  222. pos -= used;
  223. block = UT_LIST_GET_NEXT(list, block);
  224. ut_ad(block);
  225. used = dyn_block_get_used(block);
  226. }
  227. }
  228. ut_ad(block);
  229. ut_ad(dyn_block_get_used(block) >= pos);
  230. return(block->data + pos);
  231. }
  232. /****************************************************************
  233. Returns the size of stored data in a dyn array. */
  234. UNIV_INLINE
  235. ulint
  236. dyn_array_get_data_size(
  237. /*====================*/
  238. /* out: data size in bytes */
  239. dyn_array_t* arr) /* in: dyn array */
  240. {
  241. dyn_block_t* block;
  242. ulint sum  = 0;
  243. ut_ad(arr);
  244. ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
  245. if (arr->heap == NULL) {
  246. return(arr->used);
  247. }
  248. /* Get the first array block */
  249. block = dyn_array_get_first_block(arr);
  250. while (block != NULL) {
  251. sum += dyn_block_get_used(block);
  252. block = dyn_array_get_next_block(arr, block);
  253. }
  254. return(sum);
  255. }
  256. /************************************************************
  257. Pushes n bytes to a dyn array. */
  258. UNIV_INLINE
  259. void
  260. dyn_push_string(
  261. /*============*/
  262. dyn_array_t* arr, /* in: dyn array */
  263. byte* str, /* in: string to write */
  264. ulint len) /* in: string length */
  265. {
  266. byte* ptr;
  267. ulint n_copied;
  268. while (len > 0) {
  269. if (len > DYN_ARRAY_DATA_SIZE) {
  270. n_copied = DYN_ARRAY_DATA_SIZE;
  271. } else {
  272. n_copied = len;
  273. }
  274. ptr = (byte*) dyn_array_push(arr, n_copied);
  275. ut_memcpy(ptr, str, n_copied);
  276. str += n_copied;
  277. len -= n_copied;
  278. }
  279. }