1/***************************************************************************** 2 3Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License, version 2.0, as published by the 7Free Software Foundation. 8 9This program is also distributed with certain software (including but not 10limited to OpenSSL) that is licensed under separate terms, as designated in a 11particular file or component or in included license documentation. The authors 12of MySQL hereby grant you an additional permission to link the program and 13your derivative works with the separately licensed software that they have 14included with MySQL. 15 16This program is distributed in the hope that it will be useful, but WITHOUT 17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 25*****************************************************************************/ 26 27/** @file include/btr0sea.ic 28 The index tree adaptive search 29 30 Created 2/17/1996 Heikki Tuuri 31 *************************************************************************/ 32 33#include "btr0cur.h" 34#include "buf0buf.h" 35#include "dict0mem.h" 36 37/** Updates the search info. */ 38void btr_search_info_update_slow( 39 btr_search_t *info, /*!< in/out: search info */ 40 btr_cur_t *cursor); /*!< in: cursor which was just positioned */ 41 42/** Returns search info for an index. 43 @return search info; search mutex reserved */ 44UNIV_INLINE 45const btr_search_t *btr_search_get_info( 46 const dict_index_t *index) /*!< in: index */ 47{ 48 return (index->search_info); 49} 50 51/** Returns search info for an index. 52 @return search info; search mutex reserved */ 53UNIV_INLINE 54btr_search_t *btr_search_get_info(dict_index_t *index) /*!< in: index */ 55{ 56 return (index->search_info); 57} 58 59/** Updates the search info. */ 60UNIV_INLINE 61void btr_search_info_update( 62 dict_index_t *index, /*!< in: index of the cursor */ 63 btr_cur_t *cursor) /*!< in: cursor which was just positioned */ 64{ 65 ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S)); 66 ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X)); 67 68 if (dict_index_is_spatial(index) || !btr_search_enabled) { 69 return; 70 } 71 72 btr_search_t *info; 73 info = btr_search_get_info(index); 74 75 info->hash_analysis++; 76 77 if (info->hash_analysis < BTR_SEARCH_HASH_ANALYSIS) { 78 /* Do nothing */ 79 80 return; 81 } 82 83 ut_ad(cursor->flag != BTR_CUR_HASH); 84 85 btr_search_info_update_slow(info, cursor); 86} 87 88/** X-Lock the search latch (corresponding to given index) 89@param[in] index index handler */ 90UNIV_INLINE 91void btr_search_x_lock(const dict_index_t *index) { 92 rw_lock_x_lock(btr_get_search_latch(index)); 93} 94 95/** X-Unlock the search latch (corresponding to given index) 96@param[in] index index handler */ 97UNIV_INLINE 98void btr_search_x_unlock(const dict_index_t *index) { 99 rw_lock_x_unlock(btr_get_search_latch(index)); 100} 101 102/** Lock all search latches in exclusive mode. */ 103UNIV_INLINE 104void btr_search_x_lock_all() { 105 for (ulint i = 0; i < btr_ahi_parts; ++i) { 106 rw_lock_x_lock(btr_search_latches[i]); 107 } 108} 109 110/** Unlock all search latches from exclusive mode. */ 111UNIV_INLINE 112void btr_search_x_unlock_all() { 113 for (ulint i = 0; i < btr_ahi_parts; ++i) { 114 rw_lock_x_unlock(btr_search_latches[i]); 115 } 116} 117 118/** S-Lock the search latch (corresponding to given index) 119@param[in] index index handler */ 120UNIV_INLINE 121void btr_search_s_lock(const dict_index_t *index) { 122 rw_lock_s_lock(btr_get_search_latch(index)); 123} 124 125/** S-Unlock the search latch (corresponding to given index) 126@param[in] index index handler */ 127UNIV_INLINE 128void btr_search_s_unlock(const dict_index_t *index) { 129 rw_lock_s_unlock(btr_get_search_latch(index)); 130} 131 132/** Lock all search latches in shared mode. */ 133UNIV_INLINE 134void btr_search_s_lock_all() { 135 for (ulint i = 0; i < btr_ahi_parts; ++i) { 136 rw_lock_s_lock(btr_search_latches[i]); 137 } 138} 139 140/** Unlock all search latches from shared mode. */ 141UNIV_INLINE 142void btr_search_s_unlock_all() { 143 for (ulint i = 0; i < btr_ahi_parts; ++i) { 144 rw_lock_s_unlock(btr_search_latches[i]); 145 } 146} 147 148#ifdef UNIV_DEBUG 149/** Check if thread owns all the search latches. 150@param[in] mode lock mode check 151@retval true if owns all of them 152@retval false if does not own some of them */ 153UNIV_INLINE 154bool btr_search_own_all(ulint mode) { 155 for (ulint i = 0; i < btr_ahi_parts; ++i) { 156 if (!rw_lock_own(btr_search_latches[i], mode)) { 157 return (false); 158 } 159 } 160 return (true); 161} 162 163/** Check if thread owns any of the search latches. 164@param[in] mode lock mode check 165@retval true if owns any of them 166@retval false if owns no search latch */ 167UNIV_INLINE 168bool btr_search_own_any(ulint mode) { 169 for (ulint i = 0; i < btr_ahi_parts; ++i) { 170 if (rw_lock_own(btr_search_latches[i], mode)) { 171 return (true); 172 } 173 } 174 return (false); 175} 176#endif /* UNIV_DEBUG */ 177 178/** Get the adaptive hash search index latch for a b-tree. 179@param[in] index b-tree index 180@return latch */ 181UNIV_INLINE 182rw_lock_t *btr_get_search_latch(const dict_index_t *index) { 183 ut_ad(index != nullptr); 184 185 ulint ifold = ut_fold_ulint_pair(static_cast<ulint>(index->id), 186 static_cast<ulint>(index->space)); 187 188 return (btr_search_latches[ifold % btr_ahi_parts]); 189} 190 191/** Get the hash-table based on index attributes. 192A table is selected from an array of tables using pair of index-id, space-id. 193@param[in] index index handler 194@return hash table */ 195UNIV_INLINE 196hash_table_t *btr_get_search_table(const dict_index_t *index) { 197 ut_ad(index != nullptr); 198 199 ulint ifold = ut_fold_ulint_pair(static_cast<ulint>(index->id), 200 static_cast<ulint>(index->space)); 201 202 return (btr_search_sys->hash_tables[ifold % btr_ahi_parts]); 203} 204