1/*****************************************************************************
2
3Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2018, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/********************************************************************//**
21@file include/btr0sea.ic
22The index tree adaptive search
23
24Created 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 */
34static 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 */
50void
51btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor);
52
53/*********************************************************************//**
54Updates the search info. */
55static inline
56void
57btr_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. */
88static 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. */
96static 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. */
104static 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. */
112static 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 */
124static 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 */
138static 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 */
152static 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.
164A 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 */
167static 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