1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. |
4 | Copyright (c) 2018, MariaDB Corporation. |
5 | |
6 | This program is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free Software |
8 | Foundation; version 2 of the License. |
9 | |
10 | This program is distributed in the hope that it will be useful, but WITHOUT |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License along with |
15 | this program; if not, write to the Free Software Foundation, Inc., |
16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
17 | |
18 | *****************************************************************************/ |
19 | |
20 | /**************************************************//** |
21 | @file include/ha0ha.h |
22 | The hash table with external chains |
23 | |
24 | Created 8/18/1994 Heikki Tuuri |
25 | *******************************************************/ |
26 | |
27 | #ifndef ha0ha_h |
28 | #define ha0ha_h |
29 | |
30 | #include "univ.i" |
31 | |
32 | #include "hash0hash.h" |
33 | #include "page0types.h" |
34 | #include "buf0types.h" |
35 | #include "rem0types.h" |
36 | |
37 | #ifdef BTR_CUR_HASH_ADAPT |
38 | /*************************************************************//** |
39 | Looks for an element in a hash table. |
40 | @return pointer to the data of the first hash table node in chain |
41 | having the fold number, NULL if not found */ |
42 | UNIV_INLINE |
43 | const rec_t* |
44 | ha_search_and_get_data( |
45 | /*===================*/ |
46 | hash_table_t* table, /*!< in: hash table */ |
47 | ulint fold); /*!< in: folded value of the searched data */ |
48 | /*********************************************************//** |
49 | Looks for an element when we know the pointer to the data and updates |
50 | the pointer to data if found. |
51 | @return TRUE if found */ |
52 | ibool |
53 | ha_search_and_update_if_found_func( |
54 | /*===============================*/ |
55 | hash_table_t* table, /*!< in/out: hash table */ |
56 | ulint fold, /*!< in: folded value of the searched data */ |
57 | const rec_t* data, /*!< in: pointer to the data */ |
58 | #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG |
59 | buf_block_t* new_block,/*!< in: block containing new_data */ |
60 | #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
61 | const rec_t* new_data);/*!< in: new pointer to the data */ |
62 | |
63 | #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG |
64 | /** Looks for an element when we know the pointer to the data and |
65 | updates the pointer to data if found. |
66 | @param table in/out: hash table |
67 | @param fold in: folded value of the searched data |
68 | @param data in: pointer to the data |
69 | @param new_block in: block containing new_data |
70 | @param new_data in: new pointer to the data */ |
71 | # define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \ |
72 | ha_search_and_update_if_found_func(table,fold,data,new_block,new_data) |
73 | #else /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
74 | /** Looks for an element when we know the pointer to the data and |
75 | updates the pointer to data if found. |
76 | @param table in/out: hash table |
77 | @param fold in: folded value of the searched data |
78 | @param data in: pointer to the data |
79 | @param new_block ignored: block containing new_data |
80 | @param new_data in: new pointer to the data */ |
81 | # define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \ |
82 | ha_search_and_update_if_found_func(table,fold,data,new_data) |
83 | #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
84 | #endif /* BTR_CUR_HASH_ADAPT */ |
85 | |
86 | /*************************************************************//** |
87 | Creates a hash table with at least n array cells. The actual number |
88 | of cells is chosen to be a prime number slightly bigger than n. |
89 | @return own: created table */ |
90 | hash_table_t* |
91 | ib_create( |
92 | /*======*/ |
93 | ulint n, /*!< in: number of array cells */ |
94 | latch_id_t id, /*!< in: latch ID */ |
95 | ulint n_mutexes,/*!< in: number of mutexes to protect the |
96 | hash table: must be a power of 2, or 0 */ |
97 | ulint type); /*!< in: type of datastructure for which |
98 | the memory heap is going to be used e.g.: |
99 | MEM_HEAP_FOR_BTR_SEARCH or |
100 | MEM_HEAP_FOR_PAGE_HASH */ |
101 | |
102 | /** Recreate a hash table with at least n array cells. The actual number |
103 | of cells is chosen to be a prime number slightly bigger than n. |
104 | The new cells are all cleared. The heaps are recreated. |
105 | The sync objects are reused. |
106 | @param[in,out] table hash table to be resuzed (to be freed later) |
107 | @param[in] n number of array cells |
108 | @return resized new table */ |
109 | hash_table_t* |
110 | ib_recreate( |
111 | hash_table_t* table, |
112 | ulint n); |
113 | |
114 | /*************************************************************//** |
115 | Empties a hash table and frees the memory heaps. */ |
116 | void |
117 | ha_clear( |
118 | /*=====*/ |
119 | hash_table_t* table); /*!< in, own: hash table */ |
120 | |
121 | #ifdef BTR_CUR_HASH_ADAPT |
122 | /*************************************************************//** |
123 | Inserts an entry into a hash table. If an entry with the same fold number |
124 | is found, its node is updated to point to the new data, and no new node |
125 | is inserted. |
126 | @return TRUE if succeed, FALSE if no more memory could be allocated */ |
127 | ibool |
128 | ha_insert_for_fold_func( |
129 | /*====================*/ |
130 | hash_table_t* table, /*!< in: hash table */ |
131 | ulint fold, /*!< in: folded value of data; if a node with |
132 | the same fold value already exists, it is |
133 | updated to point to the same data, and no new |
134 | node is created! */ |
135 | #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG |
136 | buf_block_t* block, /*!< in: buffer block containing the data */ |
137 | #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
138 | const rec_t* data); /*!< in: data, must not be NULL */ |
139 | |
140 | #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG |
141 | /** |
142 | Inserts an entry into a hash table. If an entry with the same fold number |
143 | is found, its node is updated to point to the new data, and no new node |
144 | is inserted. |
145 | @return TRUE if succeed, FALSE if no more memory could be allocated |
146 | @param t in: hash table |
147 | @param f in: folded value of data |
148 | @param b in: buffer block containing the data |
149 | @param d in: data, must not be NULL */ |
150 | # define ha_insert_for_fold(t,f,b,d) do { \ |
151 | ha_insert_for_fold_func(t,f,b,d); \ |
152 | MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED); \ |
153 | } while(0) |
154 | #else /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
155 | /** |
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 |
158 | is inserted. |
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) do { \ |
165 | ha_insert_for_fold_func(t,f,d); \ |
166 | MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED); \ |
167 | } while (0) |
168 | #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
169 | |
170 | /*********************************************************//** |
171 | Looks for an element when we know the pointer to the data and deletes |
172 | it from the hash table if found. |
173 | @return TRUE if found */ |
174 | UNIV_INLINE |
175 | ibool |
176 | ha_search_and_delete_if_found( |
177 | /*==========================*/ |
178 | hash_table_t* table, /*!< in: hash table */ |
179 | ulint fold, /*!< in: folded value of the searched data */ |
180 | const rec_t* data); /*!< in: pointer to the data */ |
181 | |
182 | /*****************************************************************//** |
183 | Removes from the chain determined by fold all nodes whose data pointer |
184 | points to the page given. */ |
185 | void |
186 | ha_remove_all_nodes_to_page( |
187 | /*========================*/ |
188 | hash_table_t* table, /*!< in: hash table */ |
189 | ulint fold, /*!< in: fold value */ |
190 | const page_t* page); /*!< in: buffer page */ |
191 | #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG |
192 | /*************************************************************//** |
193 | Validates a given range of the cells in hash table. |
194 | @return TRUE if ok */ |
195 | ibool |
196 | ha_validate( |
197 | /*========*/ |
198 | hash_table_t* table, /*!< in: hash table */ |
199 | ulint start_index, /*!< in: start index */ |
200 | ulint end_index); /*!< in: end index */ |
201 | #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ |
202 | |
203 | /** The hash table external chain node */ |
204 | struct ha_node_t { |
205 | ulint fold; /*!< fold value for the data */ |
206 | ha_node_t* next; /*!< next chain node or NULL if none */ |
207 | #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG |
208 | buf_block_t* block; /*!< buffer block containing the data, or NULL */ |
209 | #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ |
210 | const rec_t* data; /*!< pointer to the data */ |
211 | }; |
212 | #endif /* BTR_CUR_HASH_ADAPT */ |
213 | |
214 | #if defined UNIV_DEBUG && defined BTR_CUR_HASH_ADAPT |
215 | /********************************************************************//** |
216 | Assert that the synchronization object in a hash operation involving |
217 | possible change in the hash table is held. |
218 | Note that in case of mutexes we assert that mutex is owned while in case |
219 | of rw-locks we assert that it is held in exclusive mode. */ |
220 | UNIV_INLINE |
221 | void |
222 | hash_assert_can_modify( |
223 | /*===================*/ |
224 | hash_table_t* table, /*!< in: hash table */ |
225 | ulint fold); /*!< in: fold value */ |
226 | /********************************************************************//** |
227 | Assert that the synchronization object in a hash search operation is held. |
228 | Note that in case of mutexes we assert that mutex is owned while in case |
229 | of rw-locks we assert that it is held either in x-mode or s-mode. */ |
230 | UNIV_INLINE |
231 | void |
232 | hash_assert_can_search( |
233 | /*===================*/ |
234 | hash_table_t* table, /*!< in: hash table */ |
235 | ulint fold); /*!< in: fold value */ |
236 | #else /* UNIV_DEBUG */ |
237 | #define hash_assert_can_modify(t, f) |
238 | #define hash_assert_can_search(t, f) |
239 | #endif /* UNIV_DEBUG */ |
240 | |
241 | #include "ha0ha.ic" |
242 | |
243 | #endif |
244 | |