MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hash0hash.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1997, 2011, 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 as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include "hash0hash.h"
27 #ifdef UNIV_NONINL
28 #include "hash0hash.ic"
29 #endif
30 
31 #include "mem0mem.h"
32 
33 #ifndef UNIV_HOTBACKUP
34 
35 # ifdef UNIV_PFS_MUTEX
36 UNIV_INTERN mysql_pfs_key_t hash_table_mutex_key;
37 # endif /* UNIV_PFS_MUTEX */
38 
39 # ifdef UNIV_PFS_RWLOCK
40 UNIV_INTERN mysql_pfs_key_t hash_table_rw_lock_key;
41 # endif /* UNIV_PFS_RWLOCK */
42 /************************************************************/
44 UNIV_INTERN
45 void
47 /*=============*/
49  ulint fold)
50 {
51  ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
52  mutex_enter(hash_get_mutex(table, fold));
53 }
54 
55 /************************************************************/
57 UNIV_INTERN
58 void
60 /*============*/
62  ulint fold)
63 {
64  ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
65  mutex_exit(hash_get_mutex(table, fold));
66 }
67 
68 /************************************************************/
70 UNIV_INTERN
71 void
73 /*=================*/
75 {
76  ulint i;
77 
78  ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
79  for (i = 0; i < table->n_sync_obj; i++) {
80 
81  mutex_enter(table->sync_obj.mutexes + i);
82  }
83 }
84 
85 /************************************************************/
87 UNIV_INTERN
88 void
90 /*================*/
92 {
93  ulint i;
94 
95  ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
96  for (i = 0; i < table->n_sync_obj; i++) {
97 
98  mutex_exit(table->sync_obj.mutexes + i);
99  }
100 }
101 
102 /************************************************************/
104 UNIV_INTERN
105 void
107 /*====================*/
109  ib_mutex_t* keep_mutex)
110 {
111  ulint i;
112 
113  ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
114  for (i = 0; i < table->n_sync_obj; i++) {
115 
116  ib_mutex_t* mutex = table->sync_obj.mutexes + i;
117  if (UNIV_LIKELY(keep_mutex != mutex)) {
118  mutex_exit(mutex);
119  }
120  }
121 
122  ut_ad(mutex_own(keep_mutex));
123 }
124 
125 /************************************************************/
127 UNIV_INTERN
128 void
130 /*========*/
132  ulint fold)
133 {
134 
135  rw_lock_t* lock = hash_get_lock(table, fold);
136 
137  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
138  ut_ad(lock);
139 
140 #ifdef UNIV_SYNC_DEBUG
141  ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED));
142  ut_ad(!rw_lock_own(lock, RW_LOCK_EX));
143 #endif /* UNIV_SYNC_DEBUG */
144 
145  rw_lock_s_lock(lock);
146 }
147 
148 /************************************************************/
150 UNIV_INTERN
151 void
153 /*========*/
155  ulint fold)
156 {
157 
158  rw_lock_t* lock = hash_get_lock(table, fold);
159 
160  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
161  ut_ad(lock);
162 
163 #ifdef UNIV_SYNC_DEBUG
164  ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED));
165  ut_ad(!rw_lock_own(lock, RW_LOCK_EX));
166 #endif /* UNIV_SYNC_DEBUG */
167 
168  rw_lock_x_lock(lock);
169 }
170 
171 /************************************************************/
173 UNIV_INTERN
174 void
176 /*==========*/
177 
179  ulint fold)
180 {
181 
182  rw_lock_t* lock = hash_get_lock(table, fold);
183 
184  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
185  ut_ad(lock);
186 
187 #ifdef UNIV_SYNC_DEBUG
188  ut_ad(rw_lock_own(lock, RW_LOCK_SHARED));
189 #endif /* UNIV_SYNC_DEBUG */
190 
191  rw_lock_s_unlock(lock);
192 }
193 
194 /************************************************************/
196 UNIV_INTERN
197 void
199 /*==========*/
201  ulint fold)
202 {
203  rw_lock_t* lock = hash_get_lock(table, fold);
204 
205  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
206  ut_ad(lock);
207 
208 #ifdef UNIV_SYNC_DEBUG
209  ut_ad(rw_lock_own(lock, RW_LOCK_EX));
210 #endif /* UNIV_SYNC_DEBUG */
211 
212  rw_lock_x_unlock(lock);
213 }
214 
215 /************************************************************/
217 UNIV_INTERN
218 void
220 /*============*/
222 {
223  ulint i;
224 
225  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
226  for (i = 0; i < table->n_sync_obj; i++) {
227 
228  rw_lock_t* lock = table->sync_obj.rw_locks + i;
229 #ifdef UNIV_SYNC_DEBUG
230  ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED));
231  ut_ad(!rw_lock_own(lock, RW_LOCK_EX));
232 #endif /* UNIV_SYNC_DEBUG */
233 
234  rw_lock_x_lock(lock);
235  }
236 }
237 
238 /************************************************************/
240 UNIV_INTERN
241 void
243 /*==============*/
245 {
246  ulint i;
247 
248  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
249  for (i = 0; i < table->n_sync_obj; i++) {
250 
251  rw_lock_t* lock = table->sync_obj.rw_locks + i;
252 #ifdef UNIV_SYNC_DEBUG
253  ut_ad(rw_lock_own(lock, RW_LOCK_EX));
254 #endif /* UNIV_SYNC_DEBUG */
255 
256  rw_lock_x_unlock(lock);
257  }
258 }
259 
260 /************************************************************/
262 UNIV_INTERN
263 void
265 /*==================*/
267  rw_lock_t* keep_lock)
268 {
269  ulint i;
270 
271  ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
272  for (i = 0; i < table->n_sync_obj; i++) {
273 
274  rw_lock_t* lock = table->sync_obj.rw_locks + i;
275 #ifdef UNIV_SYNC_DEBUG
276  ut_ad(rw_lock_own(lock, RW_LOCK_EX));
277 #endif /* UNIV_SYNC_DEBUG */
278 
279  if (UNIV_LIKELY(keep_lock != lock)) {
280  rw_lock_x_unlock(lock);
281  }
282  }
283 }
284 
285 #endif /* !UNIV_HOTBACKUP */
286 
287 /*************************************************************/
291 UNIV_INTERN
293 hash_create(
294 /*========*/
295  ulint n)
296 {
297  hash_cell_t* array;
298  ulint prime;
300 
301  prime = ut_find_prime(n);
302 
303  table = static_cast<hash_table_t*>(mem_alloc(sizeof(hash_table_t)));
304 
305  array = static_cast<hash_cell_t*>(
306  ut_malloc(sizeof(hash_cell_t) * prime));
307 
308  /* The default type of hash_table is HASH_TABLE_SYNC_NONE i.e.:
309  the caller is responsible for access control to the table. */
310  table->type = HASH_TABLE_SYNC_NONE;
311  table->array = array;
312  table->n_cells = prime;
313 #ifndef UNIV_HOTBACKUP
314 # if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
315  table->adaptive = FALSE;
316 # endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
317  table->n_sync_obj = 0;
318  table->sync_obj.mutexes = NULL;
319  table->heaps = NULL;
320 #endif /* !UNIV_HOTBACKUP */
321  table->heap = NULL;
322  ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
323 
324  /* Initialize the cell array */
325  hash_table_clear(table);
326 
327  return(table);
328 }
329 
330 /*************************************************************/
332 UNIV_INTERN
333 void
335 /*============*/
337 {
338  ut_ad(table);
339  ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
340 
341  ut_free(table->array);
342  mem_free(table);
343 }
344 
345 #ifndef UNIV_HOTBACKUP
346 /*************************************************************/
350 UNIV_INTERN
351 void
353 /*======================*/
355  enum hash_table_sync_t type,
357 #ifdef UNIV_SYNC_DEBUG
358  ulint sync_level,
361 #endif /* UNIV_SYNC_DEBUG */
362  ulint n_sync_obj)
364 {
365  ulint i;
366 
367  ut_ad(table);
368  ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
369  ut_a(n_sync_obj > 0);
370  ut_a(ut_is_2pow(n_sync_obj));
371 
372  table->type = type;
373 
374  switch (type) {
376  table->sync_obj.mutexes = static_cast<ib_mutex_t*>(
377  mem_alloc(n_sync_obj * sizeof(ib_mutex_t)));
378 
379  for (i = 0; i < n_sync_obj; i++) {
380  mutex_create(hash_table_mutex_key,
381  table->sync_obj.mutexes + i, sync_level);
382  }
383 
384  break;
385 
387  table->sync_obj.rw_locks = static_cast<rw_lock_t*>(
388  mem_alloc(n_sync_obj * sizeof(rw_lock_t)));
389 
390  for (i = 0; i < n_sync_obj; i++) {
391  rw_lock_create(hash_table_rw_lock_key,
392  table->sync_obj.rw_locks + i, sync_level);
393  }
394 
395  break;
396 
398  ut_error;
399  }
400 
401  table->n_sync_obj = n_sync_obj;
402 }
403 #endif /* !UNIV_HOTBACKUP */