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