| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 1996, 2015, 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/btr0sea.ic |
| 22 | The index tree adaptive search |
| 23 | |
| 24 | Created 2/17/1996 Heikki Tuuri |
| 25 | *************************************************************************/ |
| 26 | |
| 27 | #include "dict0mem.h" |
| 28 | #include "btr0cur.h" |
| 29 | #include "buf0buf.h" |
| 30 | |
| 31 | /** Create and initialize search info. |
| 32 | @param[in,out] heap heap where created |
| 33 | @return own: search info struct */ |
| 34 | static inline btr_search_t* btr_search_info_create(mem_heap_t* heap) |
| 35 | { |
| 36 | btr_search_t* info = static_cast<btr_search_t*>( |
| 37 | mem_heap_zalloc(heap, sizeof(btr_search_t))); |
| 38 | ut_d(info->magic_n = BTR_SEARCH_MAGIC_N); |
| 39 | #ifdef BTR_CUR_HASH_ADAPT |
| 40 | info->n_fields = 1; |
| 41 | info->left_side = TRUE; |
| 42 | #endif /* BTR_CUR_HASH_ADAPT */ |
| 43 | return(info); |
| 44 | } |
| 45 | |
| 46 | #ifdef BTR_CUR_HASH_ADAPT |
| 47 | /** Updates the search info. |
| 48 | @param[in,out] info search info |
| 49 | @param[in,out] cursor cursor which was just positioned */ |
| 50 | void |
| 51 | btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor); |
| 52 | |
| 53 | /*********************************************************************//** |
| 54 | Updates the search info. */ |
| 55 | static inline |
| 56 | void |
| 57 | btr_search_info_update( |
| 58 | /*===================*/ |
| 59 | dict_index_t* index, /*!< in: index of the cursor */ |
| 60 | btr_cur_t* cursor) /*!< in: cursor which was just positioned */ |
| 61 | { |
| 62 | ut_ad(!btr_search_own_any(RW_LOCK_S)); |
| 63 | ut_ad(!btr_search_own_any(RW_LOCK_X)); |
| 64 | |
| 65 | if (dict_index_is_spatial(index) || !btr_search_enabled) { |
| 66 | return; |
| 67 | } |
| 68 | |
| 69 | btr_search_t* info; |
| 70 | info = btr_search_get_info(index); |
| 71 | |
| 72 | info->hash_analysis++; |
| 73 | |
| 74 | if (info->hash_analysis < BTR_SEARCH_HASH_ANALYSIS) { |
| 75 | |
| 76 | /* Do nothing */ |
| 77 | |
| 78 | return; |
| 79 | |
| 80 | } |
| 81 | |
| 82 | ut_ad(cursor->flag != BTR_CUR_HASH); |
| 83 | |
| 84 | btr_search_info_update_slow(info, cursor); |
| 85 | } |
| 86 | |
| 87 | /** Lock all search latches in exclusive mode. */ |
| 88 | static inline void btr_search_x_lock_all() |
| 89 | { |
| 90 | for (ulint i = 0; i < btr_ahi_parts; ++i) { |
| 91 | rw_lock_x_lock(btr_search_latches[i]); |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | /** Unlock all search latches from exclusive mode. */ |
| 96 | static inline void btr_search_x_unlock_all() |
| 97 | { |
| 98 | for (ulint i = 0; i < btr_ahi_parts; ++i) { |
| 99 | rw_lock_x_unlock(btr_search_latches[i]); |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | /** Lock all search latches in shared mode. */ |
| 104 | static inline void btr_search_s_lock_all() |
| 105 | { |
| 106 | for (ulint i = 0; i < btr_ahi_parts; ++i) { |
| 107 | rw_lock_s_lock(btr_search_latches[i]); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | /** Unlock all search latches from shared mode. */ |
| 112 | static inline void btr_search_s_unlock_all() |
| 113 | { |
| 114 | for (ulint i = 0; i < btr_ahi_parts; ++i) { |
| 115 | rw_lock_s_unlock(btr_search_latches[i]); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | #ifdef UNIV_DEBUG |
| 120 | /** Check if thread owns all the search latches. |
| 121 | @param[in] mode lock mode check |
| 122 | @retval true if owns all of them |
| 123 | @retval false if does not own some of them */ |
| 124 | static inline bool btr_search_own_all(ulint mode) |
| 125 | { |
| 126 | for (ulint i = 0; i < btr_ahi_parts; ++i) { |
| 127 | if (!rw_lock_own(btr_search_latches[i], mode)) { |
| 128 | return(false); |
| 129 | } |
| 130 | } |
| 131 | return(true); |
| 132 | } |
| 133 | |
| 134 | /** Check if thread owns any of the search latches. |
| 135 | @param[in] mode lock mode check |
| 136 | @retval true if owns any of them |
| 137 | @retval false if owns no search latch */ |
| 138 | static inline bool btr_search_own_any(ulint mode) |
| 139 | { |
| 140 | for (ulint i = 0; i < btr_ahi_parts; ++i) { |
| 141 | if (rw_lock_own(btr_search_latches[i], mode)) { |
| 142 | return(true); |
| 143 | } |
| 144 | } |
| 145 | return(false); |
| 146 | } |
| 147 | #endif /* UNIV_DEBUG */ |
| 148 | |
| 149 | /** Get the adaptive hash search index latch for a b-tree. |
| 150 | @param[in] index b-tree index |
| 151 | @return latch */ |
| 152 | static inline rw_lock_t* btr_get_search_latch(const dict_index_t* index) |
| 153 | { |
| 154 | ut_ad(index != NULL); |
| 155 | ut_ad(index->table->space->id == index->table->space_id); |
| 156 | |
| 157 | ulint ifold = ut_fold_ulint_pair(ulint(index->id), |
| 158 | index->table->space_id); |
| 159 | |
| 160 | return(btr_search_latches[ifold % btr_ahi_parts]); |
| 161 | } |
| 162 | |
| 163 | /** Get the hash-table based on index attributes. |
| 164 | A table is selected from an array of tables using pair of index-id, space-id. |
| 165 | @param[in] index index handler |
| 166 | @return hash table */ |
| 167 | static inline hash_table_t* btr_get_search_table(const dict_index_t* index) |
| 168 | { |
| 169 | ut_ad(index != NULL); |
| 170 | ut_ad(index->table->space->id == index->table->space_id); |
| 171 | |
| 172 | ulint ifold = ut_fold_ulint_pair(ulint(index->id), |
| 173 | index->table->space_id); |
| 174 | |
| 175 | return(btr_search_sys->hash_tables[ifold % btr_ahi_parts]); |
| 176 | } |
| 177 | #endif /* BTR_CUR_HASH_ADAPT */ |
| 178 | |