summaryrefslogtreecommitdiff
path: root/storage/innobase/include/hash0hash.h
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2012-08-01 17:27:34 +0300
committerMichael Widenius <monty@askmonty.org>2012-08-01 17:27:34 +0300
commit1d0f70c2f894b27e98773a282871d32802f67964 (patch)
tree833e683e0ced29c4323c29a9d845703d4dfcd81b /storage/innobase/include/hash0hash.h
parent5a86a61219826aadf8d08cbc447fe438f2bf50c3 (diff)
downloadmariadb-git-1d0f70c2f894b27e98773a282871d32802f67964.tar.gz
Temporary commit of merge of MariaDB 10.0-base and MySQL 5.6
Diffstat (limited to 'storage/innobase/include/hash0hash.h')
-rw-r--r--storage/innobase/include/hash0hash.h210
1 files changed, 169 insertions, 41 deletions
diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
index b17c21a45ef..1c19ea53a23 100644
--- a/storage/innobase/include/hash0hash.h
+++ b/storage/innobase/include/hash0hash.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@@ -30,6 +30,7 @@ Created 5/20/1997 Heikki Tuuri
#include "mem0mem.h"
#ifndef UNIV_HOTBACKUP
# include "sync0sync.h"
+# include "sync0rw.h"
#endif /* !UNIV_HOTBACKUP */
typedef struct hash_table_struct hash_table_t;
@@ -40,6 +41,18 @@ typedef void* hash_node_t;
/* Fix Bug #13859: symbol collision between imap/mysql */
#define hash_create hash0_create
+/* Differnt types of hash_table based on the synchronization
+method used for it. */
+enum hash_table_sync_t {
+ HASH_TABLE_SYNC_NONE = 0, /*!< Don't use any internal
+ synchronization objects for
+ this hash_table. */
+ HASH_TABLE_SYNC_MUTEX, /*!< Use mutexes to control
+ access to this hash_table. */
+ HASH_TABLE_SYNC_RW_LOCK /*!< Use rw_locks to control
+ access to this hash_table. */
+};
+
/*************************************************************//**
Creates a hash table with >= n array cells. The actual number
of cells is chosen to be a prime number slightly bigger than n.
@@ -51,21 +64,29 @@ hash_create(
ulint n); /*!< in: number of array cells */
#ifndef UNIV_HOTBACKUP
/*************************************************************//**
-Creates a mutex array to protect a hash table. */
+Creates a sync object array array to protect a hash table.
+::sync_obj can be mutexes or rw_locks depening on the type of
+hash table. */
UNIV_INTERN
void
-hash_create_mutexes_func(
-/*=====================*/
- hash_table_t* table, /*!< in: hash table */
+hash_create_sync_obj_func(
+/*======================*/
+ hash_table_t* table, /*!< in: hash table */
+ enum hash_table_sync_t type, /*!< in: HASH_TABLE_SYNC_MUTEX
+ or HASH_TABLE_SYNC_RW_LOCK */
#ifdef UNIV_SYNC_DEBUG
- ulint sync_level, /*!< in: latching order level of the
- mutexes: used in the debug version */
+ ulint sync_level,/*!< in: latching order level
+ of the mutexes: used in the
+ debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes); /*!< in: number of mutexes */
+ ulint n_sync_obj);/*!< in: number of sync objects,
+ must be a power of 2 */
#ifdef UNIV_SYNC_DEBUG
-# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,level,n)
+# define hash_create_sync_obj(t, s, n, level) \
+ hash_create_sync_obj_func(t, s, level, n)
#else /* UNIV_SYNC_DEBUG */
-# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,n)
+# define hash_create_sync_obj(t, s, n, level) \
+ hash_create_sync_obj_func(t, s, n)
#endif /* UNIV_SYNC_DEBUG */
#endif /* !UNIV_HOTBACKUP */
@@ -87,11 +108,12 @@ hash_calc_hash(
hash_table_t* table); /*!< in: hash table */
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
-Assert that the mutex for the table in a hash operation is owned. */
-# define HASH_ASSERT_OWNED(TABLE, FOLD) \
-ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
+Assert that the mutex for the table is held */
+# define HASH_ASSERT_OWN(TABLE, FOLD) \
+ ut_ad((TABLE)->type != HASH_TABLE_SYNC_MUTEX \
+ || (mutex_own(hash_get_mutex((TABLE), FOLD))));
#else /* !UNIV_HOTBACKUP */
-# define HASH_ASSERT_OWNED(TABLE, FOLD)
+# define HASH_ASSERT_OWN(TABLE, FOLD)
#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
@@ -102,7 +124,7 @@ do {\
hash_cell_t* cell3333;\
TYPE* struct3333;\
\
- HASH_ASSERT_OWNED(TABLE, FOLD)\
+ HASH_ASSERT_OWN(TABLE, FOLD)\
\
(DATA)->NAME = NULL;\
\
@@ -124,7 +146,7 @@ do {\
#ifdef UNIV_HASH_DEBUG
# define HASH_ASSERT_VALID(DATA) ut_a((void*) (DATA) != (void*) -1)
-# define HASH_INVALIDATE(DATA, NAME) DATA->NAME = (void*) -1
+# define HASH_INVALIDATE(DATA, NAME) *(void**) (&DATA->NAME) = (void*) -1
#else
# define HASH_ASSERT_VALID(DATA) do {} while (0)
# define HASH_INVALIDATE(DATA, NAME) do {} while (0)
@@ -138,7 +160,7 @@ do {\
hash_cell_t* cell3333;\
TYPE* struct3333;\
\
- HASH_ASSERT_OWNED(TABLE, FOLD)\
+ HASH_ASSERT_OWN(TABLE, FOLD)\
\
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
\
@@ -175,7 +197,7 @@ Looks for a struct in a hash table. */
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST)\
{\
\
- HASH_ASSERT_OWNED(TABLE, FOLD)\
+ HASH_ASSERT_OWN(TABLE, FOLD)\
\
(DATA) = (TYPE) HASH_GET_FIRST(TABLE, hash_calc_hash(FOLD, TABLE));\
HASH_ASSERT_VALID(DATA);\
@@ -259,7 +281,7 @@ do {\
\
HASH_DELETE(TYPE, NAME, TABLE, fold111, NODE);\
\
- top_node111 = (TYPE*)mem_heap_get_top(\
+ top_node111 = (TYPE*) mem_heap_get_top(\
hash_get_heap(TABLE, fold111),\
sizeof(TYPE));\
\
@@ -284,11 +306,12 @@ do {\
} else {\
/* We have to look for the predecessor of the top\
node */\
- node111 = cell111->node;\
+ node111 = static_cast<TYPE*>(cell111->node);\
\
while (top_node111 != HASH_GET_NEXT(NAME, node111)) {\
\
- node111 = HASH_GET_NEXT(NAME, node111);\
+ node111 = static_cast<TYPE*>(\
+ HASH_GET_NEXT(NAME, node111));\
}\
\
/* Now we have the predecessor node */\
@@ -329,12 +352,12 @@ do {\
} while (0)
/************************************************************//**
-Gets the mutex index for a fold value in a hash table.
-@return mutex number */
+Gets the sync object index for a fold value in a hash table.
+@return index */
UNIV_INLINE
ulint
-hash_get_mutex_no(
-/*==============*/
+hash_get_sync_obj_index(
+/*====================*/
hash_table_t* table, /*!< in: hash table */
ulint fold); /*!< in: fold */
/************************************************************//**
@@ -365,6 +388,15 @@ hash_get_nth_mutex(
hash_table_t* table, /*!< in: hash table */
ulint i); /*!< in: index of the mutex */
/************************************************************//**
+Gets the nth rw_lock in a hash table.
+@return rw_lock */
+UNIV_INLINE
+rw_lock_t*
+hash_get_nth_lock(
+/*==============*/
+ hash_table_t* table, /*!< in: hash table */
+ ulint i); /*!< in: index of the rw_lock */
+/************************************************************//**
Gets the mutex for a fold value in a hash table.
@return mutex */
UNIV_INLINE
@@ -374,6 +406,15 @@ hash_get_mutex(
hash_table_t* table, /*!< in: hash table */
ulint fold); /*!< in: fold */
/************************************************************//**
+Gets the rw_lock for a fold value in a hash table.
+@return rw_lock */
+UNIV_INLINE
+rw_lock_t*
+hash_get_lock(
+/*==========*/
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN
void
@@ -403,10 +444,84 @@ void
hash_mutex_exit_all(
/*================*/
hash_table_t* table); /*!< in: hash table */
+/************************************************************//**
+Releases all but the passed in mutex of a hash table. */
+UNIV_INTERN
+void
+hash_mutex_exit_all_but(
+/*====================*/
+ hash_table_t* table, /*!< in: hash table */
+ mutex_t* keep_mutex); /*!< in: mutex to keep */
+/************************************************************//**
+s-lock a lock for a fold value in a hash table. */
+UNIV_INTERN
+void
+hash_lock_s(
+/*========*/
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+x-lock a lock for a fold value in a hash table. */
+UNIV_INTERN
+void
+hash_lock_x(
+/*========*/
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+unlock an s-lock for a fold value in a hash table. */
+UNIV_INTERN
+void
+hash_unlock_s(
+/*==========*/
+
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+unlock x-lock for a fold value in a hash table. */
+UNIV_INTERN
+void
+hash_unlock_x(
+/*==========*/
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+Reserves all the locks of a hash table, in an ascending order. */
+UNIV_INTERN
+void
+hash_lock_x_all(
+/*============*/
+ hash_table_t* table); /*!< in: hash table */
+/************************************************************//**
+Releases all the locks of a hash table, in an ascending order. */
+UNIV_INTERN
+void
+hash_unlock_x_all(
+/*==============*/
+ hash_table_t* table); /*!< in: hash table */
+/************************************************************//**
+Releases all but passed in lock of a hash table, */
+UNIV_INTERN
+void
+hash_unlock_x_all_but(
+/*==================*/
+ hash_table_t* table, /*!< in: hash table */
+ rw_lock_t* keep_lock); /*!< in: lock to keep */
+
#else /* !UNIV_HOTBACKUP */
# define hash_get_heap(table, fold) ((table)->heap)
# define hash_mutex_enter(table, fold) ((void) 0)
# define hash_mutex_exit(table, fold) ((void) 0)
+# define hash_mutex_enter_all(table) ((void) 0)
+# define hash_mutex_exit_all(table) ((void) 0)
+# define hash_mutex_exit_all_but(t, m) ((void) 0)
+# define hash_lock_s(t, f) ((void) 0)
+# define hash_lock_x(t, f) ((void) 0)
+# define hash_unlock_s(t, f) ((void) 0)
+# define hash_unlock_x(t, f) ((void) 0)
+# define hash_lock_x_all(t) ((void) 0)
+# define hash_unlock_x_all(t) ((void) 0)
+# define hash_unlock_x_all_but(t, l) ((void) 0)
#endif /* !UNIV_HOTBACKUP */
struct hash_cell_struct{
@@ -415,27 +530,40 @@ struct hash_cell_struct{
/* The hash table structure */
struct hash_table_struct {
+ enum hash_table_sync_t type; /*<! type of hash_table. */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
- ibool adaptive;/* TRUE if this is the hash table of the
- adaptive hash index */
+ ibool adaptive;/* TRUE if this is the hash
+ table of the adaptive hash
+ index */
# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- ulint n_cells;/* number of cells in the hash table */
- hash_cell_t* array; /*!< pointer to cell array */
+ ulint n_cells;/* number of cells in the hash table */
+ hash_cell_t* array; /*!< pointer to cell array */
#ifndef UNIV_HOTBACKUP
- ulint n_mutexes;/* if mutexes != NULL, then the number of
- mutexes, must be a power of 2 */
- mutex_t* mutexes;/* NULL, or an array of mutexes used to
- protect segments of the hash table */
- mem_heap_t** heaps; /*!< if this is non-NULL, hash chain nodes for
- external chaining can be allocated from these
- memory heaps; there are then n_mutexes many of
- these heaps */
+ ulint n_sync_obj;/* if sync_objs != NULL, then
+ the number of either the number
+ of mutexes or the number of
+ rw_locks depending on the type.
+ Must be a power of 2 */
+ union {
+ mutex_t* mutexes;/* NULL, or an array of mutexes
+ used to protect segments of the
+ hash table */
+ rw_lock_t* rw_locks;/* NULL, or an array of rw_lcoks
+ used to protect segments of the
+ hash table */
+ } sync_obj;
+
+ mem_heap_t** heaps; /*!< if this is non-NULL, hash
+ chain nodes for external chaining
+ can be allocated from these memory
+ heaps; there are then n_mutexes
+ many of these heaps */
#endif /* !UNIV_HOTBACKUP */
- mem_heap_t* heap;
+ mem_heap_t* heap;
#ifdef UNIV_DEBUG
- ulint magic_n;
+ ulint magic_n;
# define HASH_TABLE_MAGIC_N 76561114
#endif /* UNIV_DEBUG */
};