2005-10-27 09:29:40 +02:00
|
|
|
/************************************************************************
|
|
|
|
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
|
2006-11-21 11:34:42 +01:00
|
|
|
ha_node_set_data_func(
|
|
|
|
/*==================*/
|
2005-10-27 09:29:40 +02:00
|
|
|
ha_node_t* node, /* in: hash chain node */
|
2006-11-13 22:53:09 +01:00
|
|
|
#ifdef UNIV_DEBUG
|
|
|
|
buf_block_t* block, /* in: buffer block containing the data */
|
|
|
|
#endif /* UNIV_DEBUG */
|
2005-10-27 09:29:40 +02:00
|
|
|
void* data) /* in: pointer to the data */
|
|
|
|
{
|
2006-11-13 22:53:09 +01:00
|
|
|
#ifdef UNIV_DEBUG
|
|
|
|
node->block = block;
|
|
|
|
#endif /* UNIV_DEBUG */
|
2005-10-27 09:29:40 +02:00
|
|
|
node->data = data;
|
|
|
|
}
|
|
|
|
|
2006-11-21 11:34:42 +01:00
|
|
|
#ifdef UNIV_DEBUG
|
|
|
|
# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,b,d)
|
|
|
|
#else /* UNIV_DEBUG */
|
|
|
|
# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,d)
|
|
|
|
#endif /* UNIV_DEBUG */
|
|
|
|
|
2005-10-27 09:29:40 +02:00
|
|
|
/**********************************************************************
|
|
|
|
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) {
|
2006-11-14 11:42:50 +01:00
|
|
|
ha_delete_hash_node(table, node);
|
2005-10-27 09:29:40 +02:00
|
|
|
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|