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

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. The simple hash table utility
  3. (c) 1997 Innobase Oy
  4. Created 5/20/1997 Heikki Tuuri
  5. *******************************************************/
  6. #ifndef hash0hash_h
  7. #define hash0hash_h
  8. #include "univ.i"
  9. #include "mem0mem.h"
  10. #include "sync0sync.h"
  11. typedef struct hash_table_struct hash_table_t;
  12. typedef struct hash_cell_struct hash_cell_t;
  13. typedef void* hash_node_t;
  14. /*****************************************************************
  15. Creates a hash table with >= n array cells. The actual number
  16. of cells is chosen to be a prime number slightly bigger than n. */
  17. hash_table_t*
  18. hash_create(
  19. /*========*/
  20. /* out, own: created table */
  21. ulint n); /* in: number of array cells */
  22. /*****************************************************************
  23. Creates a mutex array to protect a hash table. */
  24. void
  25. hash_create_mutexes(
  26. /*================*/
  27. hash_table_t* table, /* in: hash table */
  28. ulint n_mutexes, /* in: number of mutexes */
  29. ulint sync_level); /* in: latching order level of the
  30. mutexes: used in the debug version */
  31. /*****************************************************************
  32. Frees a hash table. */
  33. void
  34. hash_table_free(
  35. /*============*/
  36. hash_table_t* table); /* in, own: hash table */
  37. /******************************************************************
  38. Calculates the hash value from a folded value. */
  39. UNIV_INLINE
  40. ulint
  41. hash_calc_hash(
  42. /*===========*/
  43. /* out: hashed value */
  44. ulint fold, /* in: folded value */
  45. hash_table_t* table); /* in: hash table */
  46. /************************************************************************
  47. Assert that the mutex for the table in a hash operation is owned. */
  48. #ifdef UNIV_SYNC_DEBUG
  49. # define HASH_ASSERT_OWNED(TABLE, FOLD) 
  50. ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
  51. #else
  52. # define HASH_ASSERT_OWNED(TABLE, FOLD)
  53. #endif
  54. /***********************************************************************
  55. Inserts a struct to a hash table. */
  56. #define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)
  57. do {
  58. hash_cell_t* cell3333;
  59. TYPE* struct3333;
  60. HASH_ASSERT_OWNED(TABLE, FOLD)
  61. (DATA)->NAME = NULL;
  62. cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));
  63. if (cell3333->node == NULL) {
  64. cell3333->node = DATA;
  65. } else {
  66. struct3333 = cell3333->node;
  67. while (struct3333->NAME != NULL) {
  68. struct3333 = struct3333->NAME;
  69. }
  70. struct3333->NAME = DATA;
  71. }
  72. } while (0)
  73. /***********************************************************************
  74. Deletes a struct from a hash table. */
  75. #define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)
  76. do {
  77. hash_cell_t* cell3333;
  78. TYPE* struct3333;
  79. HASH_ASSERT_OWNED(TABLE, FOLD)
  80. cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));
  81. if (cell3333->node == DATA) {
  82. cell3333->node = DATA->NAME;
  83. } else {
  84. struct3333 = cell3333->node;
  85. while (struct3333->NAME != DATA) {
  86. ut_a(struct3333);
  87. struct3333 = struct3333->NAME;
  88. }
  89. struct3333->NAME = DATA->NAME;
  90. }
  91. } while (0)
  92. /***********************************************************************
  93. Gets the first struct in a hash chain, NULL if none. */
  94. #define HASH_GET_FIRST(TABLE, HASH_VAL)
  95. (hash_get_nth_cell(TABLE, HASH_VAL)->node)
  96. /***********************************************************************
  97. Gets the next struct in a hash chain, NULL if none. */
  98. #define HASH_GET_NEXT(NAME, DATA) ((DATA)->NAME)
  99. /************************************************************************
  100. Looks for a struct in a hash table. */
  101. #define HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)
  102. {
  103. HASH_ASSERT_OWNED(TABLE, FOLD)
  104. (DATA) = HASH_GET_FIRST(TABLE, hash_calc_hash(FOLD, TABLE));
  105. while ((DATA) != NULL) {
  106. if (TEST) {
  107. break;
  108. } else {
  109. (DATA) = HASH_GET_NEXT(NAME, DATA);
  110. }
  111. }
  112. }
  113. /****************************************************************
  114. Gets the nth cell in a hash table. */
  115. UNIV_INLINE
  116. hash_cell_t*
  117. hash_get_nth_cell(
  118. /*==============*/
  119. /* out: pointer to cell */
  120. hash_table_t*  table, /* in: hash table */
  121. ulint  n); /* in: cell index */
  122. /*****************************************************************
  123. Returns the number of cells in a hash table. */
  124. UNIV_INLINE
  125. ulint
  126. hash_get_n_cells(
  127. /*=============*/
  128. /* out: number of cells */
  129. hash_table_t* table); /* in: table */
  130. /***********************************************************************
  131. Deletes a struct which is stored in the heap of the hash table, and compacts
  132. the heap. The fold value must be stored in the struct NODE in a field named
  133. 'fold'. */
  134. #define HASH_DELETE_AND_COMPACT(TYPE, NAME, TABLE, NODE)
  135. do {
  136. TYPE* node111;
  137. TYPE* top_node111;
  138. hash_cell_t* cell111;
  139. ulint fold111;
  140. fold111 = (NODE)->fold;
  141. HASH_DELETE(TYPE, NAME, TABLE, fold111, NODE);
  142. top_node111 = (TYPE*)mem_heap_get_top(
  143. hash_get_heap(TABLE, fold111),
  144. sizeof(TYPE));
  145. /* If the node to remove is not the top node in the heap, compact the
  146. heap of nodes by moving the top node in the place of NODE. */
  147. if (NODE != top_node111) {
  148. /* Copy the top node in place of NODE */
  149. *(NODE) = *top_node111;
  150. cell111 = hash_get_nth_cell(TABLE,
  151. hash_calc_hash(top_node111->fold, TABLE));
  152. /* Look for the pointer to the top node, to update it */
  153. if (cell111->node == top_node111) {
  154. /* The top node is the first in the chain */
  155. cell111->node = NODE;
  156. } else {
  157. /* We have to look for the predecessor of the top
  158. node */
  159. node111 = cell111->node;
  160. while (top_node111 != HASH_GET_NEXT(NAME, node111)) {
  161. node111 = HASH_GET_NEXT(NAME, node111);
  162. }
  163. /* Now we have the predecessor node */
  164. node111->NAME = NODE;
  165. }
  166. }
  167. /* Free the space occupied by the top node */
  168. mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));
  169. } while (0)
  170. /****************************************************************
  171. Gets the mutex index for a fold value in a hash table. */
  172. UNIV_INLINE
  173. ulint
  174. hash_get_mutex_no(
  175. /*==============*/
  176. /* out: mutex number */
  177. hash_table_t*  table, /* in: hash table */
  178. ulint  fold); /* in: fold */
  179. /****************************************************************
  180. Gets the nth heap in a hash table. */
  181. UNIV_INLINE
  182. mem_heap_t*
  183. hash_get_nth_heap(
  184. /*==============*/
  185. /* out: mem heap */
  186. hash_table_t*  table, /* in: hash table */
  187. ulint  i); /* in: index of the heap */
  188. /****************************************************************
  189. Gets the heap for a fold value in a hash table. */
  190. UNIV_INLINE
  191. mem_heap_t*
  192. hash_get_heap(
  193. /*==========*/
  194. /* out: mem heap */
  195. hash_table_t*  table, /* in: hash table */
  196. ulint  fold); /* in: fold */
  197. /****************************************************************
  198. Gets the nth mutex in a hash table. */
  199. UNIV_INLINE
  200. mutex_t*
  201. hash_get_nth_mutex(
  202. /*===============*/
  203. /* out: mutex */
  204. hash_table_t*  table, /* in: hash table */
  205. ulint  i); /* in: index of the mutex */
  206. /****************************************************************
  207. Gets the mutex for a fold value in a hash table. */
  208. UNIV_INLINE
  209. mutex_t*
  210. hash_get_mutex(
  211. /*===========*/
  212. /* out: mutex */
  213. hash_table_t*  table, /* in: hash table */
  214. ulint  fold); /* in: fold */
  215. /****************************************************************
  216. Reserves the mutex for a fold value in a hash table. */
  217. void
  218. hash_mutex_enter(
  219. /*=============*/
  220. hash_table_t*  table, /* in: hash table */
  221. ulint  fold); /* in: fold */
  222. /****************************************************************
  223. Releases the mutex for a fold value in a hash table. */
  224. void
  225. hash_mutex_exit(
  226. /*============*/
  227. hash_table_t*  table, /* in: hash table */
  228. ulint  fold); /* in: fold */
  229. /****************************************************************
  230. Reserves all the mutexes of a hash table, in an ascending order. */
  231. void
  232. hash_mutex_enter_all(
  233. /*=================*/
  234. hash_table_t*  table); /* in: hash table */
  235. /****************************************************************
  236. Releases all the mutexes of a hash table. */
  237. void
  238. hash_mutex_exit_all(
  239. /*================*/
  240. hash_table_t*  table); /* in: hash table */
  241. struct hash_cell_struct{
  242. void* node; /* hash chain node, NULL if none */
  243. };
  244. /* The hash table structure */
  245. struct hash_table_struct {
  246. ibool adaptive;/* TRUE if this is the hash table of the
  247. adaptive hash index */
  248. ulint n_cells;/* number of cells in the hash table */
  249. hash_cell_t* array; /* pointer to cell array */
  250. ulint n_mutexes;/* if mutexes != NULL, then the number of
  251. mutexes, must be a power of 2 */
  252. mutex_t* mutexes;/* NULL, or an array of mutexes used to
  253. protect segments of the hash table */
  254. mem_heap_t** heaps; /* if this is non-NULL, hash chain nodes for
  255. external chaining can be allocated from these
  256. memory heaps; there are then n_mutexes many of
  257. these heaps */
  258. mem_heap_t* heap;
  259. ulint magic_n;
  260. };
  261. #define HASH_TABLE_MAGIC_N 76561114
  262. #ifndef UNIV_NONINL
  263. #include "hash0hash.ic"
  264. #endif
  265. #endif