ha0ha.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /************************************************************************
  2. The hash table with external chains
  3. (c) 1994-1997 Innobase Oy
  4. Created 8/18/1994 Heikki Tuuri
  5. *************************************************************************/
  6. #include "ut0rnd.h"
  7. #include "mem0mem.h"
  8. /* The hash table external chain node */
  9. typedef struct ha_node_struct ha_node_t;
  10. struct ha_node_struct {
  11. ha_node_t* next; /* next chain node or NULL if none */
  12. void* data; /* pointer to the data */
  13. ulint fold; /* fold value for the data */
  14. };
  15. /***************************************************************
  16. Deletes a hash node. */
  17. void
  18. ha_delete_hash_node(
  19. /*================*/
  20. hash_table_t* table, /* in: hash table */
  21. ha_node_t* del_node); /* in: node to be deleted */
  22. /**********************************************************************
  23. Gets a hash node data. */
  24. UNIV_INLINE
  25. void*
  26. ha_node_get_data(
  27. /*=============*/
  28. /* out: pointer to the data */
  29. ha_node_t* node) /* in: hash chain node */
  30. {
  31. return(node->data);
  32. }
  33. /**********************************************************************
  34. Sets hash node data. */
  35. UNIV_INLINE
  36. void
  37. ha_node_set_data(
  38. /*=============*/
  39. ha_node_t* node, /* in: hash chain node */
  40. void* data) /* in: pointer to the data */
  41. {
  42. node->data = data;
  43. }
  44. /**********************************************************************
  45. Gets the next node in a hash chain. */
  46. UNIV_INLINE
  47. ha_node_t*
  48. ha_chain_get_next(
  49. /*==============*/
  50. /* out: next node, NULL if none */
  51. hash_table_t* table, /* in: hash table */
  52. ha_node_t* node) /* in: hash chain node */
  53. {
  54. ut_ad(table);
  55. return(node->next);
  56. }
  57. /**********************************************************************
  58. Gets the first node in a hash chain. */
  59. UNIV_INLINE
  60. ha_node_t*
  61. ha_chain_get_first(
  62. /*===============*/
  63. /* out: first node, NULL if none */
  64. hash_table_t* table, /* in: hash table */
  65. ulint fold) /* in: fold value determining the chain */
  66. {
  67. return(hash_get_nth_cell(table, hash_calc_hash(fold, table))->node);
  68. }
  69. /*****************************************************************
  70. Looks for an element in a hash table. */
  71. UNIV_INLINE
  72. ha_node_t*
  73. ha_search(
  74. /*======*/
  75. /* out: pointer to the first hash table node
  76. in chain having the fold number, NULL if not
  77. found */
  78. hash_table_t* table, /* in: hash table */
  79. ulint fold) /* in: folded value of the searched data */
  80. {
  81. ha_node_t* node;
  82. ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
  83. node = ha_chain_get_first(table, fold);
  84. while (node) {
  85. if (node->fold == fold) {
  86. return(node);
  87. }
  88. node = ha_chain_get_next(table, node);
  89. }
  90. return(NULL);
  91. }
  92. /*****************************************************************
  93. Looks for an element in a hash table. */
  94. UNIV_INLINE
  95. void*
  96. ha_search_and_get_data(
  97. /*===================*/
  98. /* out: pointer to the data of the first hash
  99. table node in chain having the fold number,
  100. NULL if not found */
  101. hash_table_t* table, /* in: hash table */
  102. ulint fold) /* in: folded value of the searched data */
  103. {
  104. ha_node_t* node;
  105. ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
  106. node = ha_chain_get_first(table, fold);
  107. while (node) {
  108. if (node->fold == fold) {
  109. return(node->data);
  110. }
  111. node = ha_chain_get_next(table, node);
  112. }
  113. return(NULL);
  114. }
  115. /*****************************************************************
  116. Returns the next matching hash table node in chain. */
  117. UNIV_INLINE
  118. ha_node_t*
  119. ha_next(
  120. /*====*/
  121. /* out: pointer to the next hash table node
  122. in chain with the fold value, NULL if not
  123. found */
  124. hash_table_t* table, /* in: hash table */
  125. ha_node_t* node) /* in: hash table node */
  126. {
  127. ulint fold;
  128. fold = node->fold;
  129. ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
  130. node = ha_chain_get_next(table, node);
  131. while (node) {
  132. if (node->fold == fold) {
  133. return(node);
  134. }
  135. node = ha_chain_get_next(table, node);
  136. }
  137. return(NULL);
  138. }
  139. /*************************************************************
  140. Looks for an element when we know the pointer to the data. */
  141. UNIV_INLINE
  142. ha_node_t*
  143. ha_search_with_data(
  144. /*================*/
  145. /* out: pointer to the hash table node, NULL
  146. if not found in the table */
  147. hash_table_t* table, /* in: hash table */
  148. ulint fold, /* in: folded value of the searched data */
  149. void* data) /* in: pointer to the data */
  150. {
  151. ha_node_t* node;
  152. ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
  153. node = ha_chain_get_first(table, fold);
  154. while (node) {
  155. if (node->data == data) {
  156. return(node);
  157. }
  158. node = ha_chain_get_next(table, node);
  159. }
  160. return(NULL);
  161. }
  162. /*************************************************************
  163. Looks for an element when we know the pointer to the data, and updates
  164. the pointer to data, if found. */
  165. UNIV_INLINE
  166. void
  167. ha_search_and_update_if_found(
  168. /*==========================*/
  169. hash_table_t* table, /* in: hash table */
  170. ulint fold, /* in: folded value of the searched data */
  171. void* data, /* in: pointer to the data */
  172. void* new_data)/* in: new pointer to the data */
  173. {
  174. ha_node_t* node;
  175. ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
  176. node = ha_search_with_data(table, fold, data);
  177. if (node) {
  178. node->data = new_data;
  179. }
  180. }
  181. /*************************************************************
  182. Looks for an element when we know the pointer to the data, and deletes
  183. it from the hash table, if found. */
  184. UNIV_INLINE
  185. ibool
  186. ha_search_and_delete_if_found(
  187. /*==========================*/
  188. /* out: TRUE if found */
  189. hash_table_t* table, /* in: hash table */
  190. ulint fold, /* in: folded value of the searched data */
  191. void* data) /* in: pointer to the data */
  192. {
  193. ha_node_t* node;
  194. ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
  195. node = ha_search_with_data(table, fold, data);
  196. if (node) {
  197. ha_delete_hash_node(table, node);
  198. return(TRUE);
  199. }
  200. return(FALSE);
  201. }
  202. /*****************************************************************
  203. Reserves the necessary hash table mutex and inserts an entry into the hash
  204. table. */
  205. UNIV_INLINE
  206. ibool
  207. ha_insert_for_fold_mutex(
  208. /*=====================*/
  209. /* out: TRUE if succeed, FALSE if no more
  210. memory could be allocated */
  211. hash_table_t* table, /* in: hash table */
  212. ulint fold, /* in: folded value of data; if a node with
  213. the same fold value already exists, it is
  214. updated to point to the same data, and no new
  215. node is created! */
  216. void* data) /* in: data, must not be NULL */
  217. {
  218. ibool ret;
  219. hash_mutex_enter(table, fold);
  220. ret = ha_insert_for_fold(table, fold, data);
  221. hash_mutex_exit(table, fold);
  222. return(ret);
  223. }