1
/*****************************************************************************
3
Copyright (C) 1994, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
21
The hash table with external chains
23
Created 8/18/1994 Heikki Tuuri
24
*******************************************************/
31
#include "hash0hash.h"
32
#include "page0types.h"
33
#include "buf0types.h"
35
/*************************************************************//**
36
Looks for an element in a hash table.
37
@return pointer to the data of the first hash table node in chain
38
having the fold number, NULL if not found */
41
ha_search_and_get_data(
42
/*===================*/
43
hash_table_t* table, /*!< in: hash table */
44
ulint fold); /*!< in: folded value of the searched data */
45
/*********************************************************//**
46
Looks for an element when we know the pointer to the data and updates
47
the pointer to data if found. */
50
ha_search_and_update_if_found_func(
51
/*===============================*/
52
hash_table_t* table, /*!< in/out: hash table */
53
ulint fold, /*!< in: folded value of the searched data */
54
void* data, /*!< in: pointer to the data */
55
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
56
buf_block_t* new_block,/*!< in: block containing new_data */
57
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
58
void* new_data);/*!< in: new pointer to the data */
60
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
61
/** Looks for an element when we know the pointer to the data and
62
updates the pointer to data if found.
63
@param table in/out: hash table
64
@param fold in: folded value of the searched data
65
@param data in: pointer to the data
66
@param new_block in: block containing new_data
67
@param new_data in: new pointer to the data */
68
# define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \
69
ha_search_and_update_if_found_func(table,fold,data,new_block,new_data)
70
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
71
/** Looks for an element when we know the pointer to the data and
72
updates the pointer to data if found.
73
@param table in/out: hash table
74
@param fold in: folded value of the searched data
75
@param data in: pointer to the data
76
@param new_block ignored: block containing new_data
77
@param new_data in: new pointer to the data */
78
# define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \
79
ha_search_and_update_if_found_func(table,fold,data,new_data)
80
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
81
/*************************************************************//**
82
Creates a hash table with at least n array cells. The actual number
83
of cells is chosen to be a prime number slightly bigger than n.
84
@return own: created table */
89
ulint n, /*!< in: number of array cells */
90
#ifdef UNIV_SYNC_DEBUG
91
ulint mutex_level, /*!< in: level of the mutexes in the latching
92
order: this is used in the debug version */
93
#endif /* UNIV_SYNC_DEBUG */
94
ulint n_mutexes); /*!< in: number of mutexes to protect the
95
hash table: must be a power of 2, or 0 */
96
#ifdef UNIV_SYNC_DEBUG
97
/** Creates a hash table.
98
@return own: created table
99
@param n_c in: number of array cells. The actual number of cells is
100
chosen to be a slightly bigger prime number.
101
@param level in: level of the mutexes in the latching order
102
@param n_m in: number of mutexes to protect the hash table;
103
must be a power of 2, or 0 */
104
# define ha_create(n_c,n_m,level) ha_create_func(n_c,level,n_m)
105
#else /* UNIV_SYNC_DEBUG */
106
/** Creates a hash table.
107
@return own: created table
108
@param n_c in: number of array cells. The actual number of cells is
109
chosen to be a slightly bigger prime number.
110
@param level in: level of the mutexes in the latching order
111
@param n_m in: number of mutexes to protect the hash table;
112
must be a power of 2, or 0 */
113
# define ha_create(n_c,n_m,level) ha_create_func(n_c,n_m)
114
#endif /* UNIV_SYNC_DEBUG */
116
/*************************************************************//**
117
Empties a hash table and frees the memory heaps. */
122
hash_table_t* table); /*!< in, own: hash table */
124
/*************************************************************//**
125
Inserts an entry into a hash table. If an entry with the same fold number
126
is found, its node is updated to point to the new data, and no new node
128
@return TRUE if succeed, FALSE if no more memory could be allocated */
131
ha_insert_for_fold_func(
132
/*====================*/
133
hash_table_t* table, /*!< in: hash table */
134
ulint fold, /*!< in: folded value of data; if a node with
135
the same fold value already exists, it is
136
updated to point to the same data, and no new
138
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
139
buf_block_t* block, /*!< in: buffer block containing the data */
140
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
141
void* data); /*!< in: data, must not be NULL */
143
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
145
Inserts an entry into a hash table. If an entry with the same fold number
146
is found, its node is updated to point to the new data, and no new node
148
@return TRUE if succeed, FALSE if no more memory could be allocated
149
@param t in: hash table
150
@param f in: folded value of data
151
@param b in: buffer block containing the data
152
@param d in: data, must not be NULL */
153
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,b,d)
154
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
156
Inserts an entry into a hash table. If an entry with the same fold number
157
is found, its node is updated to point to the new data, and no new node
159
@return TRUE if succeed, FALSE if no more memory could be allocated
160
@param t in: hash table
161
@param f in: folded value of data
162
@param b ignored: buffer block containing the data
163
@param d in: data, must not be NULL */
164
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,d)
165
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
167
/*********************************************************//**
168
Looks for an element when we know the pointer to the data and deletes
169
it from the hash table if found.
170
@return TRUE if found */
173
ha_search_and_delete_if_found(
174
/*==========================*/
175
hash_table_t* table, /*!< in: hash table */
176
ulint fold, /*!< in: folded value of the searched data */
177
void* data); /*!< in: pointer to the data */
178
#ifndef UNIV_HOTBACKUP
179
/*****************************************************************//**
180
Removes from the chain determined by fold all nodes whose data pointer
181
points to the page given. */
184
ha_remove_all_nodes_to_page(
185
/*========================*/
186
hash_table_t* table, /*!< in: hash table */
187
ulint fold, /*!< in: fold value */
188
const page_t* page); /*!< in: buffer page */
189
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
190
/*************************************************************//**
191
Validates a given range of the cells in hash table.
192
@return TRUE if ok */
197
hash_table_t* table, /*!< in: hash table */
198
ulint start_index, /*!< in: start index */
199
ulint end_index); /*!< in: end index */
200
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
201
/*************************************************************//**
202
Prints info of a hash table. */
207
FILE* file, /*!< in: file where to print */
208
hash_table_t* table); /*!< in: hash table */
209
#endif /* !UNIV_HOTBACKUP */
211
/** The hash table external chain node */
212
typedef struct ha_node_struct ha_node_t;
214
/** The hash table external chain node */
215
struct ha_node_struct {
216
ha_node_t* next; /*!< next chain node or NULL if none */
217
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
218
buf_block_t* block; /*!< buffer block containing the data, or NULL */
219
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
220
void* data; /*!< pointer to the data */
221
ulint fold; /*!< fold value for the data */
224
#ifndef UNIV_HOTBACKUP
225
/** Assert that the current thread is holding the mutex protecting a
226
hash bucket corresponding to a fold value.
227
@param table in: hash table
228
@param fold in: fold value */
229
# define ASSERT_HASH_MUTEX_OWN(table, fold) \
230
ut_ad(!(table)->mutexes || mutex_own(hash_get_mutex(table, fold)))
231
#else /* !UNIV_HOTBACKUP */
232
/** Assert that the current thread is holding the mutex protecting a
233
hash bucket corresponding to a fold value.
234
@param table in: hash table
235
@param fold in: fold value */
236
# define ASSERT_HASH_MUTEX_OWN(table, fold) ((void) 0)
237
#endif /* !UNIV_HOTBACKUP */