hash0hash.h
Upload User: tsgydb
Upload Date: 2007-04-14
Package Size: 10674k
Code Size: 9k
Category:

MySQL

Development Platform:

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. Inserts a struct to a hash table. */
  48. #define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)
  49. {
  50. hash_cell_t* cell3333;
  51. TYPE* struct3333;
  52. ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
  53. (DATA)->NAME = NULL;
  54. cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));
  55. if (cell3333->node == NULL) {
  56. cell3333->node = DATA;
  57. } else {
  58. struct3333 = cell3333->node;
  59. while (struct3333->NAME != NULL) {
  60. struct3333 = struct3333->NAME;
  61. }
  62. struct3333->NAME = DATA;
  63. }
  64. }
  65. /***********************************************************************
  66. Deletes a struct from a hash table. */
  67. #define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)
  68. {
  69. hash_cell_t* cell3333;
  70. TYPE* struct3333;
  71. ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
  72. cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));
  73. if (cell3333->node == DATA) {
  74. cell3333->node = DATA->NAME;
  75. } else {
  76. struct3333 = cell3333->node;
  77. while (struct3333->NAME != DATA) {
  78. ut_ad(struct3333)
  79. struct3333 = struct3333->NAME;
  80. }
  81. struct3333->NAME = DATA->NAME;
  82. }
  83. }
  84. /***********************************************************************
  85. Gets the first struct in a hash chain, NULL if none. */
  86. #define HASH_GET_FIRST(TABLE, HASH_VAL)
  87. (hash_get_nth_cell(TABLE, HASH_VAL)->node)
  88. /***********************************************************************
  89. Gets the next struct in a hash chain, NULL if none. */
  90. #define HASH_GET_NEXT(NAME, DATA) ((DATA)->NAME)
  91. /************************************************************************
  92. Looks for a struct in a hash table. */
  93. #define HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)
  94. {
  95. ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
  96. (DATA) = HASH_GET_FIRST(TABLE, hash_calc_hash(FOLD, TABLE));
  97. while ((DATA) != NULL) {
  98. if (TEST) {
  99. break;
  100. } else {
  101. (DATA) = HASH_GET_NEXT(NAME, DATA);
  102. }
  103. }
  104. }
  105. /****************************************************************
  106. Gets the nth cell in a hash table. */
  107. UNIV_INLINE
  108. hash_cell_t*
  109. hash_get_nth_cell(
  110. /*==============*/
  111. /* out: pointer to cell */
  112. hash_table_t*  table, /* in: hash table */
  113. ulint  n); /* in: cell index */
  114. /*****************************************************************
  115. Returns the number of cells in a hash table. */
  116. UNIV_INLINE
  117. ulint
  118. hash_get_n_cells(
  119. /*=============*/
  120. /* out: number of cells */
  121. hash_table_t* table); /* in: table */
  122. /***********************************************************************
  123. Deletes a struct which is stored in the heap of the hash table, and compacts
  124. the heap. The fold value must be stored in the struct NODE in a field named
  125. 'fold'. */
  126. #define HASH_DELETE_AND_COMPACT(TYPE, NAME, TABLE, NODE)
  127. {
  128. TYPE* node111;
  129. TYPE* top_node111;
  130. hash_cell_t* cell111;
  131. ulint fold111;
  132. fold111 = (NODE)->fold;
  133. HASH_DELETE(TYPE, NAME, TABLE, fold111, NODE);
  134. top_node111 = (TYPE*)mem_heap_get_top(
  135. hash_get_heap(TABLE, fold111),
  136. sizeof(TYPE));
  137. /* If the node to remove is not the top node in the heap, compact the
  138. heap of nodes by moving the top node in the place of NODE. */
  139. if (NODE != top_node111) {
  140. /* Copy the top node in place of NODE */
  141. *(NODE) = *top_node111;
  142. cell111 = hash_get_nth_cell(TABLE,
  143. hash_calc_hash(top_node111->fold, TABLE));
  144. /* Look for the pointer to the top node, to update it */
  145. if (cell111->node == top_node111) {
  146. /* The top node is the first in the chain */
  147. cell111->node = NODE;
  148. } else {
  149. /* We have to look for the predecessor of the top
  150. node */
  151. node111 = cell111->node;
  152. while (top_node111 != HASH_GET_NEXT(NAME, node111)) {
  153. node111 = HASH_GET_NEXT(NAME, node111);
  154. }
  155. /* Now we have the predecessor node */
  156. node111->NAME = NODE;
  157. }
  158. }
  159. /* Free the space occupied by the top node */
  160. mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));
  161. }
  162. /***********************************************************************
  163. Calculates the number of stored structs in a hash table. */
  164. #define HASH_GET_N_NODES(TYPE, NAME, TABLE, N)
  165. {
  166. hash_cell_t* cell3333;
  167. TYPE* struct3333;
  168. ulint i3333;
  169. (N) = 0;
  170. for (i3333 = 0; i3333 < hash_get_n_cells(TABLE); i3333++) {
  171. cell3333 = hash_get_nth_cell(TABLE, i3333);
  172. struct3333 = cell3333->node;
  173. while (struct3333) {
  174. (N) = (N) + 1;
  175. struct = HASH_GET_NEXT(NAME, struct3333);
  176. }
  177. }
  178. }
  179. /****************************************************************
  180. Gets the mutex index for a fold value in a hash table. */
  181. UNIV_INLINE
  182. ulint
  183. hash_get_mutex_no(
  184. /*==============*/
  185. /* out: mutex number */
  186. hash_table_t*  table, /* in: hash table */
  187. ulint  fold); /* in: fold */
  188. /****************************************************************
  189. Gets the nth heap in a hash table. */
  190. UNIV_INLINE
  191. mem_heap_t*
  192. hash_get_nth_heap(
  193. /*==============*/
  194. /* out: mem heap */
  195. hash_table_t*  table, /* in: hash table */
  196. ulint  i); /* in: index of the heap */
  197. /****************************************************************
  198. Gets the heap for a fold value in a hash table. */
  199. UNIV_INLINE
  200. mem_heap_t*
  201. hash_get_heap(
  202. /*==========*/
  203. /* out: mem heap */
  204. hash_table_t*  table, /* in: hash table */
  205. ulint  fold); /* in: fold */
  206. /****************************************************************
  207. Gets the nth mutex in a hash table. */
  208. UNIV_INLINE
  209. mutex_t*
  210. hash_get_nth_mutex(
  211. /*===============*/
  212. /* out: mutex */
  213. hash_table_t*  table, /* in: hash table */
  214. ulint  i); /* in: index of the mutex */
  215. /****************************************************************
  216. Gets the mutex for a fold value in a hash table. */
  217. UNIV_INLINE
  218. mutex_t*
  219. hash_get_mutex(
  220. /*===========*/
  221. /* out: mutex */
  222. hash_table_t*  table, /* in: hash table */
  223. ulint  fold); /* in: fold */
  224. /****************************************************************
  225. Reserves the mutex for a fold value in a hash table. */
  226. void
  227. hash_mutex_enter(
  228. /*=============*/
  229. hash_table_t*  table, /* in: hash table */
  230. ulint  fold); /* in: fold */
  231. /****************************************************************
  232. Releases the mutex for a fold value in a hash table. */
  233. void
  234. hash_mutex_exit(
  235. /*============*/
  236. hash_table_t*  table, /* in: hash table */
  237. ulint  fold); /* in: fold */
  238. /****************************************************************
  239. Reserves all the mutexes of a hash table, in an ascending order. */
  240. void
  241. hash_mutex_enter_all(
  242. /*=================*/
  243. hash_table_t*  table); /* in: hash table */
  244. /****************************************************************
  245. Releases all the mutexes of a hash table. */
  246. void
  247. hash_mutex_exit_all(
  248. /*================*/
  249. hash_table_t*  table); /* in: hash table */
  250. struct hash_cell_struct{
  251. void* node; /* hash chain node, NULL if none */
  252. };
  253. /* The hash table structure */
  254. struct hash_table_struct {
  255. ulint n_cells;/* number of cells in the hash table */
  256. hash_cell_t* array; /* pointer to cell array */
  257. ulint n_mutexes;/* if mutexes != NULL, then the number of
  258. mutexes, must be a power of 2 */
  259. mutex_t* mutexes;/* NULL, or an array of mutexes used to
  260. protect segments of the hash table */
  261. mem_heap_t** heaps; /* if this is non-NULL, hash chain nodes for
  262. external chaining can be allocated from these
  263. memory heaps; there are then n_mutexes many of
  264. these heaps */
  265. mem_heap_t* heap;
  266. ulint magic_n;
  267. };
  268. #define HASH_TABLE_MAGIC_N 76561114
  269. #ifndef UNIV_NONINL
  270. #include "hash0hash.ic"
  271. #endif
  272. #endif