summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-06-18 11:37:24 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-06-18 14:16:01 +0300
commit9159b8976f7dfe9c956608f23df42d49ba1fcbbc (patch)
tree3bae634312d8e9c7117534d7305f233fa6e6329c
parent08f6513cb2369a3d5a053a43bb945aa93a3b1da7 (diff)
downloadmariadb-git-9159b8976f7dfe9c956608f23df42d49ba1fcbbc.tar.gz
MDEV-22871: Clean up hash_table_t
HASH_TABLE_SYNC_MUTEX was kind-of used for the adaptive hash index, even though that hash table is already protected by btr_search_latches[]. HASH_TABLE_SYNC_RWLOCK was only being used for buf_pool.page_hash. It is cleaner to decouple that synchronization from hash_table_t, and move it to the actual user. buf_pool_t::page_hash_latches[]: Synchronization for buf_pool.page_hash. LATCH_ID_HASH_TABLE_MUTEX: Remove. hash_table_t::sync_obj, hash_table_t::n_sync_obj: Remove. hash_table_t::type, hash_table_sync_t: Remove. HASH_ASSERT_OWN(), hash_get_mutex(), hash_get_nth_mutex(): Remove. ib_recreate(): Merge to the only caller, buf_pool_resize_hash(). ib_create(): Merge to the callers. ha_clear(): Merge to the only caller buf_pool_t::close(). buf_pool_t::create(): Merge the ib_create() and hash_create_sync_obj() invocations. ha_insert_for_fold_func(): Clarify an assertion. buf_pool_t::page_hash_lock(): Simplify the logic. hash_assert_can_search(), hash_assert_can_modify(): Remove. These predicates were only being invoked for the adaptive hash index, while they only are effective for buf_pool.page_hash. HASH_DELETE_AND_COMPACT(): Merge to ha_delete_hash_node(). hash_get_sync_obj_index(): Remove. hash_table_t::heaps[], hash_get_nth_heap(): Remove. It was actually unused! hash_get_heap(): Remove. It was only used in ha_delete_hash_node(), where we always use hash_table_t::heap. hash_table_t::calc_hash(): Replaces hash_calc_hash().
-rw-r--r--storage/innobase/btr/btr0sea.cc10
-rw-r--r--storage/innobase/buf/buf0buf.cc128
-rw-r--r--storage/innobase/ha/ha0ha.cc263
-rw-r--r--storage/innobase/ha/hash0hash.cc109
-rw-r--r--storage/innobase/handler/ha_innodb.cc1
-rw-r--r--storage/innobase/include/buf0buf.h66
-rw-r--r--storage/innobase/include/ha0ha.h51
-rw-r--r--storage/innobase/include/ha0ha.ic13
-rw-r--r--storage/innobase/include/hash0hash.h201
-rw-r--r--storage/innobase/include/hash0hash.ic113
-rw-r--r--storage/innobase/include/mem0mem.h1
-rw-r--r--storage/innobase/include/sync0sync.h1
-rw-r--r--storage/innobase/include/sync0types.h1
-rw-r--r--storage/innobase/srv/srv0srv.cc10
-rw-r--r--storage/innobase/sync/sync0debug.cc3
-rw-r--r--storage/innobase/sync/sync0sync.cc1
16 files changed, 164 insertions, 808 deletions
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 80003fe6abc..2d1f9100f32 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -387,9 +387,13 @@ void btr_search_enable(bool resize)
ut_malloc(sizeof(hash_table_t*) * btr_ahi_parts, mem_key_ahi));
for (ulint i = 0; i < btr_ahi_parts; ++i) {
btr_search_sys->hash_tables[i] =
- ib_create((hash_size / btr_ahi_parts),
- LATCH_ID_HASH_TABLE_MUTEX,
- 0, MEM_HEAP_FOR_BTR_SEARCH);
+ hash_create(hash_size / btr_ahi_parts);
+ btr_search_sys->hash_tables[i]->heap = mem_heap_create_typed(
+ std::min<ulong>(4096,
+ MEM_MAX_ALLOC_IN_BUF / 2
+ - MEM_BLOCK_HEADER_SIZE
+ - MEM_SPACE_NEEDED(0)),
+ MEM_HEAP_FOR_BTR_SEARCH);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
btr_search_sys->hash_tables[i]->adaptive = TRUE;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index e92d65b418b..1eb28db37a2 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1523,11 +1523,10 @@ bool buf_pool_t::create()
ut_a(srv_n_page_hash_locks != 0);
ut_a(srv_n_page_hash_locks <= MAX_PAGE_HASH_LOCKS);
- page_hash= ib_create(2 * curr_size,
- LATCH_ID_HASH_TABLE_RW_LOCK,
- srv_n_page_hash_locks, MEM_HEAP_FOR_PAGE_HASH);
-
- ut_ad(!page_hash_old);
+ page_hash= hash_create(2 * curr_size);
+ for (auto i= srv_n_page_hash_locks; i--; )
+ rw_lock_create(hash_table_locks_key, &page_hash_latches[i],
+ SYNC_BUF_PAGE_HASH);
zip_hash= hash_create(2 * curr_size);
last_printout_time= time(NULL);
@@ -1605,7 +1604,8 @@ void buf_pool_t::close()
ut_free(chunks);
chunks= nullptr;
- ha_clear(page_hash);
+ for (auto i= srv_n_page_hash_locks; i--; )
+ rw_lock_free(&page_hash_latches[i]);
hash_table_free(page_hash);
hash_table_free(zip_hash);
@@ -1924,78 +1924,44 @@ inline bool buf_pool_t::withdraw_blocks()
/** resize page_hash and zip_hash */
static void buf_pool_resize_hash()
{
- hash_table_t* new_hash_table;
-
- ut_ad(buf_pool.page_hash_old == NULL);
-
- /* recreate page_hash */
- new_hash_table = ib_recreate(
- buf_pool.page_hash, 2 * buf_pool.curr_size);
-
- for (ulint i = 0; i < hash_get_n_cells(buf_pool.page_hash); i++) {
- buf_page_t* bpage;
-
- bpage = static_cast<buf_page_t*>(
- HASH_GET_FIRST(
- buf_pool.page_hash, i));
-
- while (bpage) {
- buf_page_t* prev_bpage = bpage;
- ulint fold;
-
- ut_ad(bpage->in_page_hash);
- bpage = static_cast<buf_page_t*>(
- HASH_GET_NEXT(
- hash, prev_bpage));
-
- fold = prev_bpage->id().fold();
-
- HASH_DELETE(buf_page_t, hash,
- buf_pool.page_hash, fold,
- prev_bpage);
-
- HASH_INSERT(buf_page_t, hash,
- new_hash_table, fold,
- prev_bpage);
- }
- }
-
- buf_pool.page_hash_old = buf_pool.page_hash;
- buf_pool.page_hash = new_hash_table;
-
- /* recreate zip_hash */
- new_hash_table = hash_create(2 * buf_pool.curr_size);
-
- for (ulint i = 0; i < hash_get_n_cells(buf_pool.zip_hash); i++) {
- buf_page_t* bpage;
-
- bpage = static_cast<buf_page_t*>(
- HASH_GET_FIRST(buf_pool.zip_hash, i));
+ hash_table_t *new_hash_table= hash_create(2 * buf_pool.curr_size);
- while (bpage) {
- buf_page_t* prev_bpage = bpage;
- ulint fold;
-
- bpage = static_cast<buf_page_t*>(
- HASH_GET_NEXT(
- hash, prev_bpage));
+ for (ulint i= 0; i < hash_get_n_cells(buf_pool.page_hash); i++)
+ {
+ while (buf_page_t *bpage= static_cast<buf_page_t*>
+ (HASH_GET_FIRST(buf_pool.page_hash, i)))
+ {
+ buf_page_t *prev_bpage= bpage;
+ ut_ad(bpage->in_page_hash);
+ bpage= static_cast<buf_page_t*>(HASH_GET_NEXT(hash, prev_bpage));
+ const ulint fold= prev_bpage->id().fold();
+ HASH_DELETE(buf_page_t, hash, buf_pool.page_hash, fold, prev_bpage);
+ HASH_INSERT(buf_page_t, hash, new_hash_table, fold, prev_bpage);
+ }
+ }
- fold = BUF_POOL_ZIP_FOLD(
- reinterpret_cast<buf_block_t*>(
- prev_bpage));
+ std::swap(buf_pool.page_hash->array, new_hash_table->array);
+ buf_pool.page_hash->n_cells= new_hash_table->n_cells;
+ hash_table_free(new_hash_table);
- HASH_DELETE(buf_page_t, hash,
- buf_pool.zip_hash, fold,
- prev_bpage);
+ /* recreate zip_hash */
+ new_hash_table= hash_create(2 * buf_pool.curr_size);
- HASH_INSERT(buf_page_t, hash,
- new_hash_table, fold,
- prev_bpage);
- }
- }
+ for (ulint i= 0; i < hash_get_n_cells(buf_pool.zip_hash); i++)
+ {
+ while (buf_page_t *bpage= static_cast<buf_page_t*>
+ (HASH_GET_FIRST(buf_pool.zip_hash, i)))
+ {
+ buf_page_t *prev_bpage= bpage;
+ bpage= static_cast<buf_page_t*>(HASH_GET_NEXT(hash, prev_bpage));
+ const ulint fold= BUF_POOL_ZIP_FOLD_BPAGE(prev_bpage);
+ HASH_DELETE(buf_page_t, hash, buf_pool.zip_hash, fold, prev_bpage);
+ HASH_INSERT(buf_page_t, hash, new_hash_table, fold, prev_bpage);
+ }
+ }
- hash_table_free(buf_pool.zip_hash);
- buf_pool.zip_hash = new_hash_table;
+ hash_table_free(buf_pool.zip_hash);
+ buf_pool.zip_hash= new_hash_table;
}
@@ -2162,8 +2128,10 @@ withdraw_retry:
/* Indicate critical path */
resizing.store(true, std::memory_order_relaxed);
- mutex_enter(&mutex);
- page_hash_lock_all();
+ mutex_enter(&mutex);
+ for (auto i= srv_n_page_hash_locks; i--; )
+ rw_lock_x_lock(&page_hash_latches[i]);
+
chunk_t::map_reg = UT_NEW_NOKEY(chunk_t::map());
/* add/delete chunks */
@@ -2312,13 +2280,9 @@ calc_buf_pool_size:
ib::info() << "hash tables were resized";
}
- page_hash_unlock_all();
- mutex_exit(&mutex);
-
- if (page_hash_old != NULL) {
- hash_table_free(page_hash_old);
- page_hash_old = NULL;
- }
+ mutex_exit(&mutex);
+ for (auto i= srv_n_page_hash_locks; i--; )
+ rw_lock_x_unlock(&page_hash_latches[i]);
UT_DELETE(chunk_map_old);
diff --git a/storage/innobase/ha/ha0ha.cc b/storage/innobase/ha/ha0ha.cc
index f73de63a97a..f0b5fb672cd 100644
--- a/storage/innobase/ha/ha0ha.cc
+++ b/storage/innobase/ha/ha0ha.cc
@@ -32,166 +32,6 @@ Created 8/22/1994 Heikki Tuuri
#include "btr0sea.h"
#include "page0page.h"
-/*************************************************************//**
-Creates a hash table with at least n array cells. The actual number
-of cells is chosen to be a prime number slightly bigger than n.
-@return own: created table */
-hash_table_t*
-ib_create(
-/*======*/
- ulint n, /*!< in: number of array cells */
- latch_id_t id, /*!< in: latch ID */
- ulint n_sync_obj,
- /*!< in: number of mutexes to protect the
- hash table: must be a power of 2, or 0 */
- ulint type) /*!< in: type of datastructure for which
- MEM_HEAP_FOR_PAGE_HASH */
-{
- hash_table_t* table;
-
- ut_a(type == MEM_HEAP_FOR_BTR_SEARCH
- || type == MEM_HEAP_FOR_PAGE_HASH);
-
- ut_ad(ut_is_2pow(n_sync_obj));
- table = hash_create(n);
-
- /* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
- but in practise it never should in this case, hence the asserts. */
-
- if (n_sync_obj == 0) {
- table->heap = mem_heap_create_typed(
- std::min<ulong>(
- 4096,
- MEM_MAX_ALLOC_IN_BUF / 2
- - MEM_BLOCK_HEADER_SIZE - MEM_SPACE_NEEDED(0)),
- type);
- ut_a(table->heap);
-
- return(table);
- }
-
- if (type == MEM_HEAP_FOR_PAGE_HASH) {
- /* We create a hash table protected by rw_locks for
- buf_pool.page_hash. */
- hash_create_sync_obj(
- table, HASH_TABLE_SYNC_RW_LOCK, id, n_sync_obj);
- } else {
- hash_create_sync_obj(
- table, HASH_TABLE_SYNC_MUTEX, id, n_sync_obj);
- }
-
- table->heaps = static_cast<mem_heap_t**>(
- ut_malloc_nokey(n_sync_obj * sizeof(void*)));
-
- for (ulint i = 0; i < n_sync_obj; i++) {
- table->heaps[i] = mem_heap_create_typed(
- std::min<ulong>(
- 4096,
- MEM_MAX_ALLOC_IN_BUF / 2
- - MEM_BLOCK_HEADER_SIZE - MEM_SPACE_NEEDED(0)),
- type);
- ut_a(table->heaps[i]);
- }
-
- return(table);
-}
-
-/** Recreate a hash table with at least n array cells. The actual number
-of cells is chosen to be a prime number slightly bigger than n.
-The new cells are all cleared. The heaps are recreated.
-The sync objects are reused.
-@param[in,out] table hash table to be resuzed (to be freed later)
-@param[in] n number of array cells
-@return resized new table */
-hash_table_t*
-ib_recreate(
- hash_table_t* table,
- ulint n)
-{
- /* This function is for only page_hash for now */
- ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
- ut_ad(table->n_sync_obj > 0);
-
- hash_table_t* new_table = hash_create(n);
-
- new_table->type = table->type;
- new_table->n_sync_obj = table->n_sync_obj;
- new_table->sync_obj = table->sync_obj;
-
- for (ulint i = 0; i < table->n_sync_obj; i++) {
- mem_heap_free(table->heaps[i]);
- }
- ut_free(table->heaps);
-
- new_table->heaps = static_cast<mem_heap_t**>(
- ut_malloc_nokey(new_table->n_sync_obj * sizeof(void*)));
-
- for (ulint i = 0; i < new_table->n_sync_obj; i++) {
- new_table->heaps[i] = mem_heap_create_typed(
- std::min<ulong>(
- 4096,
- MEM_MAX_ALLOC_IN_BUF / 2
- - MEM_BLOCK_HEADER_SIZE - MEM_SPACE_NEEDED(0)),
- MEM_HEAP_FOR_PAGE_HASH);
- ut_a(new_table->heaps[i]);
- }
-
- return(new_table);
-}
-
-/*************************************************************//**
-Empties a hash table and frees the memory heaps. */
-void
-ha_clear(
-/*=====*/
- hash_table_t* table) /*!< in, own: hash table */
-{
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-#ifdef BTR_CUR_HASH_ADAPT
- ut_ad(!table->adaptive || btr_search_own_all(RW_LOCK_X));
-#endif /* BTR_CUR_HASH_ADAPT */
-
- for (ulint i = 0; i < table->n_sync_obj; i++) {
- mem_heap_free(table->heaps[i]);
- }
-
- ut_free(table->heaps);
-
- switch (table->type) {
- case HASH_TABLE_SYNC_MUTEX:
- for (ulint i = 0; i < table->n_sync_obj; ++i) {
- mutex_destroy(&table->sync_obj.mutexes[i]);
- }
- ut_free(table->sync_obj.mutexes);
- table->sync_obj.mutexes = NULL;
- break;
-
- case HASH_TABLE_SYNC_RW_LOCK:
- for (ulint i = 0; i < table->n_sync_obj; ++i) {
- rw_lock_free(&table->sync_obj.rw_locks[i]);
- }
-
- ut_free(table->sync_obj.rw_locks);
- table->sync_obj.rw_locks = NULL;
- break;
-
- case HASH_TABLE_SYNC_NONE:
- /* do nothing */
- break;
- }
-
- table->n_sync_obj = 0;
- table->type = HASH_TABLE_SYNC_NONE;
-
-
- /* Clear the hash table. */
- ulint n = hash_get_n_cells(table);
-
- for (ulint i = 0; i < n; i++) {
- hash_get_nth_cell(table, i)->node = NULL;
- }
-}
-
#ifdef BTR_CUR_HASH_ADAPT
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/** Maximum number of records in a page */
@@ -199,42 +39,6 @@ static const ulint MAX_N_POINTERS
= UNIV_PAGE_SIZE_MAX / REC_N_NEW_EXTRA_BYTES;
# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-# ifdef UNIV_DEBUG
-/** Assert that the synchronization object in a hash operation involving
-possible change in the hash table is held in exclusive mode */
-void hash_assert_can_modify(hash_table_t *table, ulint fold)
-{
- switch (table->type) {
- case HASH_TABLE_SYNC_MUTEX:
- ut_ad(mutex_own(hash_get_mutex(table, fold)));
- return;
- case HASH_TABLE_SYNC_RW_LOCK:
- ut_ad(buf_pool.page_hash_lock_own_flagged(fold, RW_LOCK_FLAG_X));
- return;
- case HASH_TABLE_SYNC_NONE:
- return;
- }
- ut_ad(0);
-}
-
-/** Assert that the synchronization object in a hash operation involving
-possible change in the hash table is held in share dor exclusive mode */
-void hash_assert_can_search(hash_table_t *table, ulint fold)
-{
- switch (table->type) {
- case HASH_TABLE_SYNC_MUTEX:
- ut_ad(mutex_own(hash_get_mutex(table, fold)));
- return;
- case HASH_TABLE_SYNC_RW_LOCK:
- ut_ad(buf_pool.page_hash_lock_own_flagged(fold, RW_LOCK_FLAG_X |
- RW_LOCK_FLAG_S));
- return;
- case HASH_TABLE_SYNC_NONE:
- return;
- }
-}
-# endif
-
/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
@@ -262,10 +66,10 @@ ha_insert_for_fold_func(
ut_ad(data);
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+ ut_ad(table->heap->type & MEM_HEAP_BTR_SEARCH);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- hash_assert_can_modify(table, fold);
ut_ad(btr_search_enabled);
hash = hash_calc_hash(fold, table);
@@ -296,16 +100,12 @@ ha_insert_for_fold_func(
}
/* We have to allocate a new chain node */
-
node = static_cast<ha_node_t*>(
- mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t)));
+ mem_heap_alloc(table->heap, sizeof(ha_node_t)));
if (node == NULL) {
/* It was a btr search type memory heap and at the moment
no more memory could be allocated: return */
-
- ut_ad(hash_get_heap(table, fold)->type & MEM_HEAP_BTR_SEARCH);
-
return(FALSE);
}
@@ -342,10 +142,8 @@ ha_insert_for_fold_func(
#ifdef UNIV_DEBUG
/** Verify if latch corresponding to the hash table is x-latched
-@param[in] table hash table */
-static
-void
-ha_btr_search_latch_x_locked(const hash_table_t* table)
+@param table hash table */
+void ha_btr_search_latch_x_locked(const hash_table_t* table)
{
ulint i;
for (i = 0; i < btr_ahi_parts; ++i) {
@@ -372,13 +170,53 @@ ha_delete_hash_node(
ut_d(ha_btr_search_latch_x_locked(table));
ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- if (table->adaptive) {
- ut_a(del_node->block->frame == page_align(del_node->data));
- ut_a(del_node->block->n_pointers-- < MAX_N_POINTERS);
- }
+ ut_a(table->adaptive);
+ ut_a(del_node->block->frame == page_align(del_node->data));
+ ut_a(del_node->block->n_pointers-- < MAX_N_POINTERS);
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
+ ha_node_t* node;
+
+ const ulint fold = del_node->fold;
+
+ HASH_DELETE(ha_node_t, next, table, fold, del_node);
+
+ ha_node_t* top_node = (ha_node_t*) mem_heap_get_top(table->heap,
+ sizeof(ha_node_t));
+
+ /* If the node to remove is not the top node in the heap, compact the
+ heap of nodes by moving the top node in the place of del_node. */
+
+ if (del_node != top_node) {
+ /* Copy the top node in place of del_node */
+
+ *del_node = *top_node;
+
+ hash_cell_t* cell = hash_get_nth_cell(
+ table, hash_calc_hash(top_node->fold, table));
+
+ /* Look for the pointer to the top node, to update it */
+
+ if (cell->node == top_node) {
+ /* The top node is the first in the chain */
+ cell->node = del_node;
+ } else {
+ /* We have to look for the predecessor */
+ node = static_cast<ha_node_t*>(cell->node);
+
+ while (top_node != HASH_GET_NEXT(next, node)) {
+ node = static_cast<ha_node_t*>(
+ HASH_GET_NEXT(next, node));
+ }
+
+ /* Now we have the predecessor node */
+ node->next = del_node;
+ }
+ }
+
+ /* Free the space occupied by the top node */
+
+ mem_heap_free_top(table->heap, sizeof(ha_node_t));
}
/*********************************************************//**
@@ -400,7 +238,6 @@ ha_search_and_update_if_found_func(
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- hash_assert_can_modify(table, fold);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -444,8 +281,8 @@ ha_remove_all_nodes_to_page(
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- hash_assert_can_modify(table, fold);
ut_ad(btr_search_enabled);
+ ut_d(ha_btr_search_latch_x_locked(table));
node = ha_chain_get_first(table, fold);
diff --git a/storage/innobase/ha/hash0hash.cc b/storage/innobase/ha/hash0hash.cc
index 17e443a8bc8..6a8c84a349d 100644
--- a/storage/innobase/ha/hash0hash.cc
+++ b/storage/innobase/ha/hash0hash.cc
@@ -28,47 +28,21 @@ Created 5/20/1997 Heikki Tuuri
#include "mem0mem.h"
#include "sync0sync.h"
-/*************************************************************//**
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n.
-@return own: created table */
-hash_table_t*
-hash_create(
-/*========*/
- ulint n) /*!< in: number of array cells */
+/**
+Create a hash table.
+@param n the minimum number of hash array elements
+@return created table (with n_cells being a prime, at least n) */
+hash_table_t *hash_create(ulint n)
{
- hash_cell_t* array;
- ulint prime;
- hash_table_t* table;
-
- prime = ut_find_prime(n);
-
- table = static_cast<hash_table_t*>(
- ut_malloc_nokey(sizeof(hash_table_t)));
-
- array = static_cast<hash_cell_t*>(
- ut_malloc_nokey(sizeof(hash_cell_t) * prime));
-
- /* The default type of hash_table is HASH_TABLE_SYNC_NONE i.e.:
- the caller is responsible for access control to the table. */
- table->type = HASH_TABLE_SYNC_NONE;
- table->array = array;
- table->n_cells = prime;
-#ifdef BTR_CUR_HASH_ADAPT
-# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- table->adaptive = FALSE;
-# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-#endif /* BTR_CUR_HASH_ADAPT */
- table->n_sync_obj = 0;
- table->sync_obj.mutexes = NULL;
- table->heaps = NULL;
- table->heap = NULL;
- ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
-
- /* Initialize the cell array */
- hash_table_clear(table);
-
- return(table);
+ ulint prime= ut_find_prime(n);
+
+ hash_table_t *table= static_cast<hash_table_t*>
+ (ut_zalloc_nokey(sizeof *table));
+ table->array= static_cast<hash_cell_t*>(ut_zalloc_nokey(sizeof(hash_cell_t) *
+ prime));
+ table->n_cells= prime;
+ ut_d(table->magic_n= HASH_TABLE_MAGIC_N);
+ return table;
}
/*************************************************************//**
@@ -83,58 +57,3 @@ hash_table_free(
ut_free(table->array);
ut_free(table);
}
-
-/*************************************************************//**
-Creates a sync object array to protect a hash table.
-::sync_obj can be mutexes or rw_locks depening on the type of
-hash table. */
-void
-hash_create_sync_obj(
-/*=================*/
- hash_table_t* table, /*!< in: hash table */
- enum hash_table_sync_t type, /*!< in: HASH_TABLE_SYNC_MUTEX
- or HASH_TABLE_SYNC_RW_LOCK */
- latch_id_t id, /*!< in: latch ID */
- ulint n_sync_obj)/*!< in: number of sync objects,
- must be a power of 2 */
-{
- ut_a(n_sync_obj > 0);
- ut_a(ut_is_2pow(n_sync_obj));
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-
- table->type = type;
-
- switch (table->type) {
- case HASH_TABLE_SYNC_MUTEX:
- table->sync_obj.mutexes = static_cast<ib_mutex_t*>(
- ut_malloc_nokey(n_sync_obj * sizeof(ib_mutex_t)));
-
- for (ulint i = 0; i < n_sync_obj; i++) {
- mutex_create(id, table->sync_obj.mutexes + i);
- }
-
- break;
-
- case HASH_TABLE_SYNC_RW_LOCK: {
-
- latch_level_t level = sync_latch_get_level(id);
-
- ut_a(level != SYNC_UNKNOWN);
-
- table->sync_obj.rw_locks = static_cast<rw_lock_t*>(
- ut_malloc_nokey(n_sync_obj * sizeof(rw_lock_t)));
-
- for (ulint i = 0; i < n_sync_obj; i++) {
- rw_lock_create(hash_table_locks_key,
- table->sync_obj.rw_locks + i, level);
- }
-
- break;
- }
-
- case HASH_TABLE_SYNC_NONE:
- ut_error;
- }
-
- table->n_sync_obj = n_sync_obj;
-}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 00a226d5982..75ee30476f7 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -531,7 +531,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(fts_optimize_mutex),
PSI_KEY(fts_doc_id_mutex),
PSI_KEY(log_flush_order_mutex),
- PSI_KEY(hash_table_mutex),
PSI_KEY(ibuf_bitmap_mutex),
PSI_KEY(ibuf_mutex),
PSI_KEY(ibuf_pessimistic_insert_mutex),
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 4b77c6965ea..71d06db01e9 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1612,43 +1612,40 @@ public:
/** Get a page_hash latch. */
rw_lock_t *hash_lock_get_low(ulint fold) const
{
- return page_hash->sync_obj.rw_locks +
- hash_get_sync_obj_index(page_hash, fold);
+ return page_hash_latches +
+ ut_2pow_remainder(page_hash->calc_hash(fold),
+ ulint{srv_n_page_hash_locks});
}
-#ifdef UNIV_DEBUG
- /** Check whether a page_hash latch is being held */
- bool page_hash_lock_own_flagged(ulint fold, rw_lock_flags_t flagged) const
+private:
+ /** Get a page_hash latch. */
+ rw_lock_t *hash_lock_get_low(ulint fold, ulint n_cells) const
{
- return rw_lock_own_flagged(hash_lock_get_low(fold), flagged);
+ return page_hash_latches +
+ ut_2pow_remainder(ut_hash_ulint(fold, n_cells),
+ ulint{srv_n_page_hash_locks});
}
-#endif
+public:
/** Acquire a page_hash bucket latch, tolerating concurrent resize()
@tparam exclusive whether the latch is to be acquired exclusively
@param fold hash bucket key */
template<bool exclusive> rw_lock_t *page_hash_lock(ulint fold)
{
- rw_lock_t *latch= hash_lock_get_low(fold);
- if (exclusive)
- rw_lock_x_lock(latch);
- else
- rw_lock_s_lock(latch);
- rw_lock_t *l;
- while ((l= hash_lock_get_low(fold)) != latch)
+ for (;;)
{
+ auto n_cells= page_hash->n_cells;
+ rw_lock_t *latch= hash_lock_get_low(fold, n_cells);
if (exclusive)
- rw_lock_x_unlock(latch);
+ rw_lock_x_lock(latch);
else
- rw_lock_s_unlock(latch);
- /* FIXME: what if we resize() completes several times while we
- are not holding any latch here? Is the latch guaranteed to be valid? */
+ rw_lock_s_lock(latch);
+ if (UNIV_LIKELY(n_cells == page_hash->n_cells))
+ return latch;
if (exclusive)
- rw_lock_x_lock(l);
+ rw_lock_x_unlock(latch);
else
- rw_lock_s_lock(l);
- latch= l;
+ rw_lock_s_unlock(latch);
}
- return latch;
}
/** Look up a block descriptor.
@@ -1728,24 +1725,6 @@ public:
return page_hash_get_locked<false,watch>(page_id, page_id.fold(), nullptr);
}
- /** Acquire exclusive latches on all page_hash buckets. */
- void page_hash_lock_all() const
- {
- ut_ad(page_hash->magic_n == HASH_TABLE_MAGIC_N);
- ut_ad(page_hash->type == HASH_TABLE_SYNC_RW_LOCK);
- for (ulint i= 0; i < page_hash->n_sync_obj; i++)
- rw_lock_x_lock(&page_hash->sync_obj.rw_locks[i]);
- }
- /** Release exclusive latches on all the page_hash buckets. */
- void page_hash_unlock_all() const
- {
- ut_ad(page_hash->magic_n == HASH_TABLE_MAGIC_N);
- ut_ad(page_hash->type == HASH_TABLE_SYNC_RW_LOCK);
-
- for (ulint i = 0; i < page_hash->n_sync_obj; i++)
- rw_lock_x_unlock(&page_hash->sync_obj.rw_locks[i]);
- }
-
/** Determine if a block is a sentinel for a buffer pool watch.
@param bpage page descriptor
@return whether bpage a sentinel for a buffer pool watch */
@@ -1894,10 +1873,11 @@ public:
Atomic_counter<uint32_t> read_ahead_area;
/** Hash table of file pages (buf_page_t::in_file() holds),
- indexed by page_id_t. Protected by both mutex and hash_lock_get(id). */
+ indexed by page_id_t. Protected by both mutex and page_hash_latches[]. */
hash_table_t *page_hash;
- hash_table_t* page_hash_old; /*!< old pointer to page_hash to be
- freed after resizing buffer pool */
+ /** Latches protecting page_hash */
+ mutable rw_lock_t page_hash_latches[MAX_PAGE_HASH_LOCKS];
+
hash_table_t* zip_hash; /*!< hash table of buf_block_t blocks
whose frames are allocated to the
zip buddy system,
diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h
index 5822fde2d04..3b3e511c9f5 100644
--- a/storage/innobase/include/ha0ha.h
+++ b/storage/innobase/include/ha0ha.h
@@ -19,7 +19,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
/**************************************************//**
@file include/ha0ha.h
-The hash table with external chains
+The hash table interface for the adaptive hash index
Created 8/18/1994 Heikki Tuuri
*******************************************************/
@@ -81,41 +81,6 @@ updates the pointer to data if found.
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
#endif /* BTR_CUR_HASH_ADAPT */
-/*************************************************************//**
-Creates a hash table with at least n array cells. The actual number
-of cells is chosen to be a prime number slightly bigger than n.
-@return own: created table */
-hash_table_t*
-ib_create(
-/*======*/
- ulint n, /*!< in: number of array cells */
- latch_id_t id, /*!< in: latch ID */
- ulint n_mutexes,/*!< in: number of mutexes to protect the
- hash table: must be a power of 2, or 0 */
- ulint type); /*!< in: type of datastructure for which
- the memory heap is going to be used e.g.:
- MEM_HEAP_FOR_BTR_SEARCH or
- MEM_HEAP_FOR_PAGE_HASH */
-
-/** Recreate a hash table with at least n array cells. The actual number
-of cells is chosen to be a prime number slightly bigger than n.
-The new cells are all cleared. The heaps are recreated.
-The sync objects are reused.
-@param[in,out] table hash table to be resuzed (to be freed later)
-@param[in] n number of array cells
-@return resized new table */
-hash_table_t*
-ib_recreate(
- hash_table_t* table,
- ulint n);
-
-/*************************************************************//**
-Empties a hash table and frees the memory heaps. */
-void
-ha_clear(
-/*=====*/
- hash_table_t* table); /*!< in, own: hash table */
-
#ifdef BTR_CUR_HASH_ADAPT
/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
@@ -207,20 +172,8 @@ struct ha_node_t {
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
const rec_t* data; /*!< pointer to the data */
};
-#endif /* BTR_CUR_HASH_ADAPT */
-
-#if defined UNIV_DEBUG && defined BTR_CUR_HASH_ADAPT
-/** Assert that the synchronization object in a hash operation involving
-possible change in the hash table is held in exclusive mode */
-void hash_assert_can_modify(hash_table_t *table, ulint fold);
-/** Assert that the synchronization object in a hash operation involving
-possible change in the hash table is held in share dor exclusive mode */
-void hash_assert_can_search(hash_table_t *table, ulint fold);
-#else /* UNIV_DEBUG */
-#define hash_assert_can_modify(t, f)
-#define hash_assert_can_search(t, f)
-#endif /* UNIV_DEBUG */
#include "ha0ha.ic"
+#endif /* BTR_CUR_HASH_ADAPT */
#endif
diff --git a/storage/innobase/include/ha0ha.ic b/storage/innobase/include/ha0ha.ic
index c83f4c35e81..57f21c02324 100644
--- a/storage/innobase/include/ha0ha.ic
+++ b/storage/innobase/include/ha0ha.ic
@@ -19,7 +19,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
/********************************************************************//**
@file include/ha0ha.ic
-The hash table with external chains
+The hash table interface for the adaptive hash index
Created 8/18/1994 Heikki Tuuri
*************************************************************************/
@@ -110,7 +110,6 @@ ha_search_and_get_data(
hash_table_t* table, /*!< in: hash table */
ulint fold) /*!< in: folded value of the searched data */
{
- hash_assert_can_search(table, fold);
ut_ad(btr_search_enabled);
for (const ha_node_t* node = ha_chain_get_first(table, fold);
@@ -139,8 +138,6 @@ ha_search_with_data(
{
ha_node_t* node;
- hash_assert_can_search(table, fold);
-
ut_ad(btr_search_enabled);
node = ha_chain_get_first(table, fold);
@@ -165,6 +162,12 @@ ha_delete_hash_node(
hash_table_t* table, /*!< in: hash table */
ha_node_t* del_node); /*!< in: node to be deleted */
+#ifdef UNIV_DEBUG
+/** Verify if latch corresponding to the hash table is x-latched
+@param table hash table */
+void ha_btr_search_latch_x_locked(const hash_table_t* table);
+#endif /* UNIV_DEBUG */
+
/*********************************************************//**
Looks for an element when we know the pointer to the data, and deletes
it from the hash table, if found.
@@ -179,7 +182,7 @@ ha_search_and_delete_if_found(
{
ha_node_t* node;
- hash_assert_can_modify(table, fold);
+ ut_d(ha_btr_search_latch_x_locked(table));
ut_ad(btr_search_enabled);
node = ha_search_with_data(table, fold, data);
diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
index 94a5f3a02f7..29e242a540d 100644
--- a/storage/innobase/include/hash0hash.h
+++ b/storage/innobase/include/hash0hash.h
@@ -31,47 +31,19 @@ Created 5/20/1997 Heikki Tuuri
#include "sync0rw.h"
struct hash_table_t;
-struct hash_cell_t;
-
+struct hash_cell_t{
+ void* node; /*!< hash chain node, NULL if none */
+};
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.
-@return own: created table */
-hash_table_t*
-hash_create(
-/*========*/
- ulint n); /*!< in: number of array cells */
-
-/*************************************************************//**
-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. */
-void
-hash_create_sync_obj(
-/*=================*/
- hash_table_t* table, /*!< in: hash table */
- hash_table_sync_t type, /*!< in: HASH_TABLE_SYNC_MUTEX
- or HASH_TABLE_SYNC_RW_LOCK */
- latch_id_t id, /*!< in: mutex/rw_lock ID */
- ulint n_sync_obj);/*!< in: number of sync objects,
- must be a power of 2 */
+/**
+Create a hash table.
+@param n the minimum number of hash array elements
+@return created table (with n_cells being a prime, at least n) */
+hash_table_t *hash_create(ulint n);
/*************************************************************//**
Frees a hash table. */
@@ -79,20 +51,8 @@ void
hash_table_free(
/*============*/
hash_table_t* table); /*!< in, own: hash table */
-/**************************************************************//**
-Calculates the hash value from a folded value.
-@return hashed value */
-UNIV_INLINE
-ulint
-hash_calc_hash(
-/*===========*/
- ulint fold, /*!< in: folded value */
- hash_table_t* table); /*!< in: hash table */
-/********************************************************************//**
-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))));
+
+#define hash_calc_hash(FOLD, TABLE) (TABLE)->calc_hash(FOLD)
/*******************************************************************//**
Inserts a struct to a hash table. */
@@ -102,8 +62,6 @@ do {\
hash_cell_t* cell3333;\
TYPE* struct3333;\
\
- HASH_ASSERT_OWN(TABLE, FOLD)\
-\
(DATA)->NAME = NULL;\
\
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
@@ -130,8 +88,6 @@ do { \
hash_cell_t* cell3333; \
TYPE* struct3333; \
\
- HASH_ASSERT_OWN(TABLE, FOLD) \
- \
(DATA)->NAME = NULL; \
\
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
@@ -163,8 +119,6 @@ do {\
hash_cell_t* cell3333;\
TYPE* struct3333;\
\
- HASH_ASSERT_OWN(TABLE, FOLD)\
-\
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
\
if (cell3333->node == DATA) {\
@@ -211,9 +165,6 @@ Gets the next struct in a hash chain, NULL if none. */
Looks for a struct in a hash table. */
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST)\
{\
-\
- HASH_ASSERT_OWN(TABLE, FOLD)\
-\
(DATA) = (TYPE) HASH_GET_FIRST(TABLE, hash_calc_hash(FOLD, TABLE));\
HASH_ASSERT_VALID(DATA);\
\
@@ -280,65 +231,6 @@ ulint
hash_get_n_cells(
/*=============*/
hash_table_t* table); /*!< in: table */
-/*******************************************************************//**
-Deletes a struct which is stored in the heap of the hash table, and compacts
-the heap. The fold value must be stored in the struct NODE in a field named
-'fold'. */
-
-#define HASH_DELETE_AND_COMPACT(TYPE, NAME, TABLE, NODE)\
-do {\
- TYPE* node111;\
- TYPE* top_node111;\
- hash_cell_t* cell111;\
- ulint fold111;\
-\
- fold111 = (NODE)->fold;\
-\
- HASH_DELETE(TYPE, NAME, TABLE, fold111, NODE);\
-\
- top_node111 = (TYPE*) mem_heap_get_top(\
- hash_get_heap(TABLE, fold111),\
- sizeof(TYPE));\
-\
- /* If the node to remove is not the top node in the heap, compact the\
- heap of nodes by moving the top node in the place of NODE. */\
-\
- if (NODE != top_node111) {\
-\
- /* Copy the top node in place of NODE */\
-\
- *(NODE) = *top_node111;\
-\
- cell111 = hash_get_nth_cell(TABLE,\
- hash_calc_hash(top_node111->fold, TABLE));\
-\
- /* Look for the pointer to the top node, to update it */\
-\
- if (cell111->node == top_node111) {\
- /* The top node is the first in the chain */\
-\
- cell111->node = NODE;\
- } else {\
- /* We have to look for the predecessor of the top\
- node */\
- node111 = static_cast<TYPE*>(cell111->node);\
-\
- while (top_node111 != HASH_GET_NEXT(NAME, node111)) {\
-\
- node111 = static_cast<TYPE*>(\
- HASH_GET_NEXT(NAME, node111));\
- }\
-\
- /* Now we have the predecessor node */\
-\
- node111->NAME = NODE;\
- }\
- }\
-\
- /* Free the space occupied by the top node */\
-\
- mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));\
-} while (0)
/****************************************************************//**
Move all hash table entries from OLD_TABLE to NEW_TABLE. */
@@ -367,59 +259,8 @@ do {\
}\
} while (0)
-/************************************************************//**
-Gets the sync object index for a fold value in a hash table.
-@return index */
-UNIV_INLINE
-ulint
-hash_get_sync_obj_index(
-/*====================*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold); /*!< in: fold */
-/************************************************************//**
-Gets the nth heap in a hash table.
-@return mem heap */
-UNIV_INLINE
-mem_heap_t*
-hash_get_nth_heap(
-/*==============*/
- hash_table_t* table, /*!< in: hash table */
- ulint i); /*!< in: index of the heap */
-/************************************************************//**
-Gets the heap for a fold value in a hash table.
-@return mem heap */
-UNIV_INLINE
-mem_heap_t*
-hash_get_heap(
-/*==========*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold); /*!< in: fold */
-/************************************************************//**
-Gets the nth mutex in a hash table.
-@return mutex */
-UNIV_INLINE
-ib_mutex_t*
-hash_get_nth_mutex(
-/*===============*/
- hash_table_t* table, /*!< in: hash table */
- ulint i); /*!< in: index of the mutex */
-/************************************************************//**
-Gets the mutex for a fold value in a hash table.
-@return mutex */
-UNIV_INLINE
-ib_mutex_t*
-hash_get_mutex(
-/*===========*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold); /*!< in: fold */
-
-struct hash_cell_t{
- void* node; /*!< hash chain node, NULL if none */
-};
-
/* The hash table structure */
struct hash_table_t {
- enum hash_table_sync_t type; /*<! type of hash_table. */
#ifdef BTR_CUR_HASH_ADAPT
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ibool adaptive;/* TRUE if this is the hash
@@ -429,31 +270,13 @@ struct hash_table_t {
#endif /* BTR_CUR_HASH_ADAPT */
ulint n_cells;/* number of cells in the hash table */
hash_cell_t* array; /*!< pointer to cell array */
-
- 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 {
- ib_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_locks
- used to protect segments of the
- buf_pool.page_hash */
- } 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 */
mem_heap_t* heap;
#ifdef UNIV_DEBUG
ulint magic_n;
# define HASH_TABLE_MAGIC_N 76561114
#endif /* UNIV_DEBUG */
+
+ ulint calc_hash(ulint fold) const { return ut_hash_ulint(fold, n_cells); }
};
#include "hash0hash.ic"
diff --git a/storage/innobase/include/hash0hash.ic b/storage/innobase/include/hash0hash.ic
index cc717ec8559..63661b041fd 100644
--- a/storage/innobase/include/hash0hash.ic
+++ b/storage/innobase/include/hash0hash.ic
@@ -68,116 +68,3 @@ hash_get_n_cells(
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
return(table->n_cells);
}
-
-/**************************************************************//**
-Calculates the hash value from a folded value.
-@return hashed value */
-UNIV_INLINE
-ulint
-hash_calc_hash(
-/*===========*/
- ulint fold, /*!< in: folded value */
- hash_table_t* table) /*!< in: hash table */
-{
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- return(ut_hash_ulint(fold, table->n_cells));
-}
-
-/************************************************************//**
-Gets the sync object index for a fold value in a hash table.
-@return index */
-UNIV_INLINE
-ulint
-hash_get_sync_obj_index(
-/*====================*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold) /*!< in: fold */
-{
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- ut_ad(table->type != HASH_TABLE_SYNC_NONE);
- ut_ad(ut_is_2pow(table->n_sync_obj));
- return(ut_2pow_remainder(hash_calc_hash(fold, table),
- table->n_sync_obj));
-}
-
-/************************************************************//**
-Gets the nth heap in a hash table.
-@return mem heap */
-UNIV_INLINE
-mem_heap_t*
-hash_get_nth_heap(
-/*==============*/
- hash_table_t* table, /*!< in: hash table */
- ulint i) /*!< in: index of the heap */
-{
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- ut_ad(table->type != HASH_TABLE_SYNC_NONE);
- ut_ad(i < table->n_sync_obj);
-
- return(table->heaps[i]);
-}
-
-/************************************************************//**
-Gets the heap for a fold value in a hash table.
-@return mem heap */
-UNIV_INLINE
-mem_heap_t*
-hash_get_heap(
-/*==========*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold) /*!< in: fold */
-{
- ulint i;
-
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-
- if (table->heap) {
- return(table->heap);
- }
-
- i = hash_get_sync_obj_index(table, fold);
-
- return(hash_get_nth_heap(table, i));
-}
-
-/************************************************************//**
-Gets the nth mutex in a hash table.
-@return mutex */
-UNIV_INLINE
-ib_mutex_t*
-hash_get_nth_mutex(
-/*===============*/
- hash_table_t* table, /*!< in: hash table */
- ulint i) /*!< in: index of the mutex */
-{
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
- ut_ad(i < table->n_sync_obj);
-
- return(table->sync_obj.mutexes + i);
-}
-
-/************************************************************//**
-Gets the mutex for a fold value in a hash table.
-@return mutex */
-UNIV_INLINE
-ib_mutex_t*
-hash_get_mutex(
-/*===========*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold) /*!< in: fold */
-{
- ulint i;
-
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-
- i = hash_get_sync_obj_index(table, fold);
-
- return(hash_get_nth_mutex(table, i));
-}
diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index ad4393ba51b..b7fd9c098a6 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/include/mem0mem.h
@@ -58,7 +58,6 @@ buffer pool; the latter method is used for very big heaps */
/** Different type of heaps in terms of which datastructure is using them */
#define MEM_HEAP_FOR_BTR_SEARCH (MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER)
-#define MEM_HEAP_FOR_PAGE_HASH (MEM_HEAP_DYNAMIC)
#define MEM_HEAP_FOR_LOCK_HEAP (MEM_HEAP_BUFFER)
/** The following start size is used for the first block in the memory heap if
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index 8c45f415ef2..7eb8250b63d 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -62,7 +62,6 @@ extern mysql_pfs_key_t fts_delete_mutex_key;
extern mysql_pfs_key_t fts_optimize_mutex_key;
extern mysql_pfs_key_t fts_doc_id_mutex_key;
extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
-extern mysql_pfs_key_t hash_table_mutex_key;
extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index d7ba055c403..0aa1326509e 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -295,7 +295,6 @@ enum latch_id_t {
LATCH_ID_FTS_OPTIMIZE,
LATCH_ID_FTS_DOC_ID,
LATCH_ID_FTS_PLL_TOKENIZE,
- LATCH_ID_HASH_TABLE_MUTEX,
LATCH_ID_IBUF_BITMAP,
LATCH_ID_IBUF,
LATCH_ID_IBUF_PESSIMISTIC_INSERT,
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index bf2d04acbf8..ab0bf1164ee 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -970,10 +970,7 @@ srv_printf_innodb_monitor(
const hash_table_t* table = btr_search_sys->hash_tables[i];
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
- /* this is only used for buf_pool.page_hash */
- ut_ad(!table->heaps);
- /* this is used for the adaptive hash index */
- ut_ad(table->heap);
+ ut_ad(table->heap->type == MEM_HEAP_FOR_BTR_SEARCH);
const mem_heap_t* heap = table->heap;
/* The heap may change during the following call,
@@ -1140,10 +1137,7 @@ next:
ut_ad(ht);
ut_ad(ht->heap);
- /* Multiple mutexes/heaps are currently never used for adaptive
- hash index tables. */
- ut_ad(!ht->n_sync_obj);
- ut_ad(!ht->heaps);
+ ut_ad(ht->heap->type == MEM_HEAP_FOR_BTR_SEARCH);
mem_adaptive_hash += mem_heap_get_size(ht->heap)
+ ht->n_cells * sizeof(hash_cell_t);
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 8ad3c4d0119..e370dc86f34 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -1294,9 +1294,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(FTS_PLL_TOKENIZE, SYNC_FTS_TOKENIZE,
fts_pll_tokenize_mutex_key);
- LATCH_ADD_MUTEX(HASH_TABLE_MUTEX, SYNC_BUF_PAGE_HASH,
- hash_table_mutex_key);
-
LATCH_ADD_MUTEX(IBUF_BITMAP, SYNC_IBUF_BITMAP_MUTEX,
ibuf_bitmap_mutex_key);
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index 068f15a77d8..85db39047ec 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -49,7 +49,6 @@ mysql_pfs_key_t fts_delete_mutex_key;
mysql_pfs_key_t fts_optimize_mutex_key;
mysql_pfs_key_t fts_doc_id_mutex_key;
mysql_pfs_key_t fts_pll_tokenize_mutex_key;
-mysql_pfs_key_t hash_table_mutex_key;
mysql_pfs_key_t ibuf_bitmap_mutex_key;
mysql_pfs_key_t ibuf_mutex_key;
mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;