/************************************************************************ The hash table with external chains (c) 1994-1997 Innobase Oy Created 8/18/1994 Heikki Tuuri *************************************************************************/ #include "ut0rnd.h" #include "mem0mem.h" /*************************************************************** Deletes a hash node. */ void ha_delete_hash_node( /*================*/ hash_table_t* table, /* in: hash table */ ha_node_t* del_node); /* in: node to be deleted */ /********************************************************************** Gets a hash node data. */ UNIV_INLINE void* ha_node_get_data( /*=============*/ /* out: pointer to the data */ ha_node_t* node) /* in: hash chain node */ { return(node->data); } /********************************************************************** Sets hash node data. */ UNIV_INLINE void ha_node_set_data( /*=============*/ ha_node_t* node, /* in: hash chain node */ void* data) /* in: pointer to the data */ { node->data = data; } /********************************************************************** Gets the next node in a hash chain. */ UNIV_INLINE ha_node_t* ha_chain_get_next( /*==============*/ /* out: next node, NULL if none */ ha_node_t* node) /* in: hash chain node */ { return(node->next); } /********************************************************************** Gets the first node in a hash chain. */ UNIV_INLINE ha_node_t* ha_chain_get_first( /*===============*/ /* out: first node, NULL if none */ hash_table_t* table, /* in: hash table */ ulint fold) /* in: fold value determining the chain */ { return(hash_get_nth_cell(table, hash_calc_hash(fold, table))->node); } /***************************************************************** Looks for an element in a hash table. */ UNIV_INLINE ha_node_t* ha_search( /*======*/ /* out: pointer to the first hash table node in chain having the fold number, NULL if not found */ hash_table_t* table, /* in: hash table */ ulint fold) /* in: folded value of the searched data */ { ha_node_t* node; #ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); #endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); while (node) { if (node->fold == fold) { return(node); } node = ha_chain_get_next(node); } return(NULL); } /***************************************************************** Looks for an element in a hash table. */ UNIV_INLINE void* ha_search_and_get_data( /*===================*/ /* out: pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ hash_table_t* table, /* in: hash table */ ulint fold) /* in: folded value of the searched data */ { ha_node_t* node; #ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); #endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); while (node) { if (node->fold == fold) { return(node->data); } node = ha_chain_get_next(node); } return(NULL); } /************************************************************* Looks for an element when we know the pointer to the data. */ UNIV_INLINE ha_node_t* ha_search_with_data( /*================*/ /* out: pointer to the hash table node, NULL if not found in the table */ hash_table_t* table, /* in: hash table */ ulint fold, /* in: folded value of the searched data */ void* data) /* in: pointer to the data */ { ha_node_t* node; #ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); #endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); while (node) { if (node->data == data) { return(node); } node = ha_chain_get_next(node); } return(NULL); } /************************************************************* Looks for an element when we know the pointer to the data, and deletes it from the hash table, if found. */ UNIV_INLINE ibool ha_search_and_delete_if_found( /*==========================*/ /* out: TRUE if found */ hash_table_t* table, /* in: hash table */ ulint fold, /* in: folded value of the searched data */ void* data) /* in: pointer to the data */ { ha_node_t* node; #ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); #endif /* UNIV_SYNC_DEBUG */ node = ha_search_with_data(table, fold, data); if (node) { ha_delete_hash_node(table, node); return(TRUE); } return(FALSE); } /***************************************************************** Reserves the necessary hash table mutex and inserts an entry into the hash table. */ UNIV_INLINE ibool ha_insert_for_fold_mutex( /*=====================*/ /* out: TRUE if succeed, FALSE if no more memory could be allocated */ hash_table_t* table, /* in: hash table */ ulint fold, /* in: folded value of data; if a node with the same fold value already exists, it is updated to point to the same data, and no new node is created! */ void* data) /* in: data, must not be NULL */ { ibool ret; hash_mutex_enter(table, fold); ret = ha_insert_for_fold(table, fold, data); hash_mutex_exit(table, fold); return(ret); }