1 /*****************************************************************************
2 
3 Copyright (c) 1994, 2018, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/ha0ha.h
28  The hash table with external chains
29 
30  Created 8/18/1994 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef ha0ha_h
34 #define ha0ha_h
35 
36 #include "univ.i"
37 
38 #include "buf0types.h"
39 #include "hash0hash.h"
40 #include "page0types.h"
41 #include "rem0types.h"
42 
43 /** Looks for an element in a hash table.
44 @param[in]	table	hash table
45 @param[in]	fold	folded value of the searched data
46 @return pointer to the data of the first hash table node in chain
47 having the fold number, NULL if not found */
48 UNIV_INLINE
49 const rec_t *ha_search_and_get_data(hash_table_t *table, ulint fold);
50 
51 /** Looks for an element when we know the pointer to the data and updates
52  the pointer to data if found.
53  @return true if found */
54 ibool ha_search_and_update_if_found_func(
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 
85 /** Creates a hash table with at least n array cells.  The actual number
86  of cells is chosen to be a prime number slightly bigger than n.
87  @return own: created table */
88 hash_table_t *ib_create(
89     ulint n,         /*!< in: number of array cells */
90     latch_id_t id,   /*!< in: latch ID */
91     ulint n_mutexes, /*!< in: number of mutexes to protect the
92                    hash table: must be a power of 2, or 0 */
93     ulint type);     /*!< in: type of datastructure for which
94                      the memory heap is going to be used e.g.:
95                      MEM_HEAP_FOR_BTR_SEARCH or
96                      MEM_HEAP_FOR_PAGE_HASH */
97 
98 /** Recreate a hash table with at least n array cells. The actual number
99 of cells is chosen to be a prime number slightly bigger than n.
100 The new cells are all cleared. The heaps are recreated.
101 The sync objects are reused.
102 @param[in,out]	table	hash table to be resuzed (to be freed later)
103 @param[in]	n	number of array cells
104 @return	resized new table */
105 hash_table_t *ib_recreate(hash_table_t *table, ulint n);
106 
107 /** Empties a hash table and frees the memory heaps. */
108 void ha_clear(hash_table_t *table); /*!< in, own: hash table */
109 
110 /** Inserts an entry into a hash table. If an entry with the same fold number
111  is found, its node is updated to point to the new data, and no new node
112  is inserted.
113  @return true if succeed, false if no more memory could be allocated */
114 ibool ha_insert_for_fold_func(
115     hash_table_t *table, /*!< in: hash table */
116     ulint fold,          /*!< in: folded value of data; if a node with
117                          the same fold value already exists, it is
118                          updated to point to the same data, and no new
119                          node is created! */
120 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
121     buf_block_t *block, /*!< in: buffer block containing the data */
122 #endif                  /* UNIV_AHI_DEBUG || UNIV_DEBUG */
123     const rec_t *data); /*!< in: data, must not be NULL */
124 
125 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
126 /**
127 Inserts an entry into a hash table. If an entry with the same fold number
128 is found, its node is updated to point to the new data, and no new node
129 is inserted.
130 @return true if succeed, false if no more memory could be allocated
131 @param t in: hash table
132 @param f in: folded value of data
133 @param b in: buffer block containing the data
134 @param d in: data, must not be NULL */
135 #define ha_insert_for_fold(t, f, b, d)            \
136   do {                                            \
137     ha_insert_for_fold_func(t, f, b, d);          \
138     MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED); \
139   } while (0)
140 #else /* UNIV_AHI_DEBUG || 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 ignored: buffer block containing the data
149 @param d in: data, must not be NULL */
150 #define ha_insert_for_fold(t, f, b, d)            \
151   do {                                            \
152     ha_insert_for_fold_func(t, f, d);             \
153     MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED); \
154   } while (0)
155 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
156 
157 /** Looks for an element when we know the pointer to the data and deletes it
158 from the hash table if found.
159 @param[in]	table	hash table
160 @param[in]	fold	folded value of the searched data
161 @param[in]	data	pointer to the data
162 @return true if found */
163 UNIV_INLINE
164 ibool ha_search_and_delete_if_found(hash_table_t *table, ulint fold,
165                                     const rec_t *data);
166 
167 #ifndef UNIV_HOTBACKUP
168 /** Removes from the chain determined by fold all nodes whose data pointer
169  points to the page given. */
170 void ha_remove_all_nodes_to_page(hash_table_t *table, /*!< in: hash table */
171                                  ulint fold,          /*!< in: fold value */
172                                  const page_t *page); /*!< in: buffer page */
173 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
174 /** Validates a given range of the cells in hash table.
175  @return true if ok */
176 ibool ha_validate(hash_table_t *table, /*!< in: hash table */
177                   ulint start_index,   /*!< in: start index */
178                   ulint end_index);    /*!< in: end index */
179 #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
180 /** Prints info of a hash table. */
181 void ha_print_info(FILE *file,           /*!< in: file where to print */
182                    hash_table_t *table); /*!< in: hash table */
183 #endif                                   /* !UNIV_HOTBACKUP */
184 
185 /** The hash table external chain node */
186 struct ha_node_t {
187   ulint fold;      /*!< fold value for the data */
188   ha_node_t *next; /*!< next chain node or NULL if none */
189 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
190   buf_block_t *block; /*!< buffer block containing the data, or NULL */
191 #endif                /* UNIV_AHI_DEBUG || UNIV_DEBUG */
192   const rec_t *data;  /*!< pointer to the data */
193 };
194 
195 #ifdef UNIV_DEBUG
196 /** Assert that the synchronization object in a hash operation involving
197 possible change in the hash table is held.
198 Note that in case of mutexes we assert that mutex is owned while in case of
199 rw-locks we assert that it is held in exclusive mode.
200 @param[in]	table	hash table
201 @param[in]	fold	fold value */
202 UNIV_INLINE
203 void hash_assert_can_modify(hash_table_t *table, ulint fold);
204 
205 /** Assert that the synchronization object in a hash search operation is held.
206 Note that in case of mutexes we assert that mutex is owned while in case of
207 rw-locks we assert that it is held either in x-mode or s-mode.
208 @param[in]	table	hash table
209 @param[in]	fold	fold value */
210 UNIV_INLINE
211 void hash_assert_can_search(hash_table_t *table, ulint fold);
212 #else /* UNIV_DEBUG */
213 #define hash_assert_can_modify(t, f)
214 #define hash_assert_can_search(t, f)
215 #endif /* UNIV_DEBUG */
216 
217 #include "ha0ha.ic"
218 
219 #endif
220