diff options
Diffstat (limited to 'storage/xtradb/include/ha0ha.ic')
-rw-r--r-- | storage/xtradb/include/ha0ha.ic | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/storage/xtradb/include/ha0ha.ic b/storage/xtradb/include/ha0ha.ic new file mode 100644 index 00000000000..9d0e396e200 --- /dev/null +++ b/storage/xtradb/include/ha0ha.ic @@ -0,0 +1,246 @@ +/***************************************************************************** + +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/********************************************************************//** +@file include/ha0ha.ic +The hash table with external chains + +Created 8/18/1994 Heikki Tuuri +*************************************************************************/ + +#include "ut0rnd.h" +#include "mem0mem.h" +#include "btr0types.h" + +/***********************************************************//** +Deletes a hash node. */ +UNIV_INTERN +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. +@return pointer to the data */ +UNIV_INLINE +const rec_t* +ha_node_get_data( +/*=============*/ + const ha_node_t* node) /*!< in: hash chain node */ +{ + return(node->data); +} + +/******************************************************************//** +Sets hash node data. */ +UNIV_INLINE +void +ha_node_set_data_func( +/*==================*/ + ha_node_t* node, /*!< in: hash chain node */ +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG + buf_block_t* block, /*!< in: buffer block containing the data */ +#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + const rec_t* data) /*!< in: pointer to the data */ +{ +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG + node->block = block; +#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + node->data = data; +} + +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG +/** Sets hash node data. +@param n in: hash chain node +@param b in: buffer block containing the data +@param d in: pointer to the data */ +# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,b,d) +#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */ +/** Sets hash node data. +@param n in: hash chain node +@param b in: buffer block containing the data +@param d in: pointer to the data */ +# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,d) +#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + +/******************************************************************//** +Gets the next node in a hash chain. +@return next node, NULL if none */ +UNIV_INLINE +ha_node_t* +ha_chain_get_next( +/*==============*/ + ha_node_t* node) /*!< in: hash chain node */ +{ + return(node->next); +} + +/******************************************************************//** +Gets the first node in a hash chain. +@return first node, NULL if none */ +UNIV_INLINE +ha_node_t* +ha_chain_get_first( +/*===============*/ + hash_table_t* table, /*!< in: hash table */ + ulint fold) /*!< in: fold value determining the chain */ +{ + return((ha_node_t*) + hash_get_nth_cell(table, hash_calc_hash(fold, table))->node); +} + +#ifdef UNIV_DEBUG +/********************************************************************//** +Assert that the synchronization object in a hash operation involving +possible change in the hash table is held. +Note that in case of mutexes we assert that mutex is owned while in case +of rw-locks we assert that it is held in exclusive mode. */ +UNIV_INLINE +void +hash_assert_can_modify( +/*===================*/ + hash_table_t* table, /*!< in: hash table */ + ulint fold) /*!< in: fold value */ +{ + if (table->type == HASH_TABLE_SYNC_MUTEX) { + ut_ad(mutex_own(hash_get_mutex(table, fold))); + } else if (table->type == HASH_TABLE_SYNC_RW_LOCK) { +# ifdef UNIV_SYNC_DEBUG + prio_rw_lock_t* lock = hash_get_lock(table, fold); + ut_ad(rw_lock_own(lock, RW_LOCK_EX)); +# endif + } else { + ut_ad(table->type == HASH_TABLE_SYNC_NONE); + } +} + +/********************************************************************//** +Assert that the synchronization object in a hash search operation is held. +Note that in case of mutexes we assert that mutex is owned while in case +of rw-locks we assert that it is held either in x-mode or s-mode. */ +UNIV_INLINE +void +hash_assert_can_search( +/*===================*/ + hash_table_t* table, /*!< in: hash table */ + ulint fold) /*!< in: fold value */ +{ + if (table->type == HASH_TABLE_SYNC_MUTEX) { + ut_ad(mutex_own(hash_get_mutex(table, fold))); + } else if (table->type == HASH_TABLE_SYNC_RW_LOCK) { +# ifdef UNIV_SYNC_DEBUG + prio_rw_lock_t* lock = hash_get_lock(table, fold); + ut_ad(rw_lock_own(lock, RW_LOCK_EX) + || rw_lock_own(lock, RW_LOCK_SHARED)); +# endif + } else { + ut_ad(table->type == HASH_TABLE_SYNC_NONE); + } +} +#endif /* UNIV_DEBUG */ + +/*************************************************************//** +Looks for an element in a hash table. +@return pointer to the data of the first hash table node in chain +having the fold number, NULL if not found */ +UNIV_INLINE +const rec_t* +ha_search_and_get_data( +/*===================*/ + hash_table_t* table, /*!< in: hash table */ + ulint fold) /*!< in: folded value of the searched data */ +{ + ha_node_t* node; + + hash_assert_can_search(table, fold); + ut_ad(btr_search_enabled); + + 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. +@return pointer to the hash table node, NULL if not found in the table */ +UNIV_INLINE +ha_node_t* +ha_search_with_data( +/*================*/ + hash_table_t* table, /*!< in: hash table */ + ulint fold, /*!< in: folded value of the searched data */ + const rec_t* data) /*!< in: pointer to the data */ +{ + ha_node_t* node; + + hash_assert_can_search(table, fold); + + ut_ad(btr_search_enabled); + + 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. +@return TRUE if found */ +UNIV_INLINE +ibool +ha_search_and_delete_if_found( +/*==========================*/ + hash_table_t* table, /*!< in: hash table */ + ulint fold, /*!< in: folded value of the searched data */ + const rec_t* data) /*!< in: pointer to the data */ +{ + ha_node_t* node; + + hash_assert_can_modify(table, fold); + ut_ad(btr_search_enabled); + + node = ha_search_with_data(table, fold, data); + + if (node) { + ha_delete_hash_node(table, node); + + return(TRUE); + } + + return(FALSE); +} |