summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-06-18 12:26:28 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-06-18 14:16:01 +0300
commitcfd3d70ccbbfcf3fdec034be446317741dfae824 (patch)
tree205817c9ea9252de9f8988ab76da82dc7d0bd7e2
parentbf3c862faa8efed4a662725ec27586cd69e9228e (diff)
downloadmariadb-git-cfd3d70ccbbfcf3fdec034be446317741dfae824.tar.gz
MDEV-22871: Remove pointer indirection for InnoDB hash_table_t
hash_get_n_cells(): Remove. Access n_cells directly. hash_get_nth_cell(): Remove. Access array directly. hash_table_clear(): Replaced with hash_table_t::clear(). hash_table_create(), hash_table_free(): Remove. hash0hash.cc: Remove.
-rw-r--r--extra/mariabackup/xtrabackup.cc93
-rw-r--r--storage/innobase/CMakeLists.txt2
-rw-r--r--storage/innobase/btr/btr0btr.cc6
-rw-r--r--storage/innobase/btr/btr0sea.cc13
-rw-r--r--storage/innobase/buf/buf0buddy.cc6
-rw-r--r--storage/innobase/buf/buf0buf.cc49
-rw-r--r--storage/innobase/buf/buf0lru.cc4
-rw-r--r--storage/innobase/buf/buf0rea.cc6
-rw-r--r--storage/innobase/dict/dict0dict.cc85
-rw-r--r--storage/innobase/fil/fil0fil.cc19
-rw-r--r--storage/innobase/gis/gis0sea.cc4
-rw-r--r--storage/innobase/ha/ha0storage.cc5
-rw-r--r--storage/innobase/ha/hash0hash.cc60
-rw-r--r--storage/innobase/include/buf0buf.h20
-rw-r--r--storage/innobase/include/dict0dict.h15
-rw-r--r--storage/innobase/include/dict0priv.ic2
-rw-r--r--storage/innobase/include/fil0fil.h5
-rw-r--r--storage/innobase/include/ha0ha.ic3
-rw-r--r--storage/innobase/include/ha0storage.ic12
-rw-r--r--storage/innobase/include/hash0hash.h72
-rw-r--r--storage/innobase/include/hash0hash.ic67
-rw-r--r--storage/innobase/include/lock0lock.h12
-rw-r--r--storage/innobase/include/lock0lock.ic9
-rw-r--r--storage/innobase/lock/lock0lock.cc161
-rw-r--r--storage/innobase/lock/lock0prdt.cc22
-rw-r--r--storage/innobase/trx/trx0i_s.cc12
26 files changed, 284 insertions, 480 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index bd2519ae7c0..0b53f1382ea 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -157,16 +157,16 @@ typedef std::list<regex_t> regex_list_t;
static regex_list_t regex_include_list;
static regex_list_t regex_exclude_list;
-static hash_table_t* tables_include_hash = NULL;
-static hash_table_t* tables_exclude_hash = NULL;
+static hash_table_t tables_include_hash;
+static hash_table_t tables_exclude_hash;
char *xtrabackup_databases = NULL;
char *xtrabackup_databases_file = NULL;
char *xtrabackup_databases_exclude = NULL;
-static hash_table_t* databases_include_hash = NULL;
-static hash_table_t* databases_exclude_hash = NULL;
+static hash_table_t databases_include_hash;
+static hash_table_t databases_exclude_hash;
-static hash_table_t* inc_dir_tables_hash;
+static hash_table_t inc_dir_tables_hash;
struct xb_filter_entry_struct{
char* name;
@@ -2256,7 +2256,7 @@ check_if_table_matches_filters(const char *name,
const regex_list_t& regex_list,
hash_table_t* tables_hash)
{
- if (regex_list.empty() && !tables_hash) {
+ if (regex_list.empty() && !tables_hash->array) {
return(FALSE);
}
@@ -2264,11 +2264,8 @@ check_if_table_matches_filters(const char *name,
return(TRUE);
}
- if (tables_hash && find_filter_in_hashtable(name, tables_hash, NULL)) {
- return(TRUE);
- }
-
- return FALSE;
+ return tables_hash->array &&
+ find_filter_in_hashtable(name, tables_hash, NULL);
}
enum skip_database_check_result {
@@ -2294,8 +2291,8 @@ check_if_skip_database(
/* There are some filters for databases, check them */
xb_filter_entry_t* database = NULL;
- if (databases_exclude_hash &&
- find_filter_in_hashtable(name, databases_exclude_hash,
+ if (databases_exclude_hash.array &&
+ find_filter_in_hashtable(name, &databases_exclude_hash,
&database) &&
!database->has_tables) {
/* Database is found and there are no tables specified,
@@ -2303,8 +2300,8 @@ check_if_skip_database(
return DATABASE_SKIP;
}
- if (databases_include_hash) {
- if (!find_filter_in_hashtable(name, databases_include_hash,
+ if (databases_include_hash.array) {
+ if (!find_filter_in_hashtable(name, &databases_include_hash,
&database)) {
/* Database isn't found, skip the database */
return DATABASE_SKIP;
@@ -2328,8 +2325,7 @@ check_if_skip_database_by_path(
const char* path /*!< in: path to the db directory. */
)
{
- if (databases_include_hash == NULL &&
- databases_exclude_hash == NULL) {
+ if (!databases_include_hash.array && !databases_exclude_hash.array) {
return(FALSE);
}
@@ -2373,10 +2369,10 @@ check_if_skip_table(
if (regex_exclude_list.empty() &&
regex_include_list.empty() &&
- tables_include_hash == NULL &&
- tables_exclude_hash == NULL &&
- databases_include_hash == NULL &&
- databases_exclude_hash == NULL) {
+ !tables_include_hash.array &&
+ !tables_exclude_hash.array &&
+ !databases_include_hash.array &&
+ !databases_exclude_hash.array) {
return(FALSE);
}
@@ -2408,22 +2404,22 @@ check_if_skip_table(
without truncating the #P#... suffix so we can backup individual
partitions with regexps like '^test[.]t#P#p5' */
if (check_if_table_matches_filters(buf, regex_exclude_list,
- tables_exclude_hash)) {
+ &tables_exclude_hash)) {
return(TRUE);
}
if (check_if_table_matches_filters(buf, regex_include_list,
- tables_include_hash)) {
+ &tables_include_hash)) {
return(FALSE);
}
if ((eptr = strstr(buf, "#P#")) != NULL) {
*eptr = 0;
if (check_if_table_matches_filters(buf, regex_exclude_list,
- tables_exclude_hash)) {
+ &tables_exclude_hash)) {
return (TRUE);
}
if (check_if_table_matches_filters(buf, regex_include_list,
- tables_include_hash)) {
+ &tables_include_hash)) {
return(FALSE);
}
}
@@ -2436,7 +2432,7 @@ check_if_skip_table(
if (skip_database == DATABASE_SKIP_SOME_TABLES ||
!regex_include_list.empty() ||
- tables_include_hash) {
+ tables_include_hash.array) {
/* Include lists are present, but qualified name
failed to match any.*/
@@ -3461,17 +3457,17 @@ xb_filter_entry_t*
xb_add_filter(
/*========================*/
const char* name, /*!< in: name of table/database */
- hash_table_t** hash) /*!< in/out: hash to insert into */
+ hash_table_t* hash) /*!< in/out: hash to insert into */
{
xb_filter_entry_t* entry;
entry = xb_new_filter_entry(name);
- if (UNIV_UNLIKELY(*hash == NULL)) {
- *hash = hash_create(1000);
+ if (UNIV_UNLIKELY(!hash->array)) {
+ hash->create(1000);
}
HASH_INSERT(xb_filter_entry_t,
- name_hash, *hash,
+ name_hash, hash,
ut_fold_string(entry->name),
entry);
@@ -3509,8 +3505,8 @@ void
xb_register_filter_entry(
/*=====================*/
const char* name, /*!< in: name */
- hash_table_t** databases_hash,
- hash_table_t** tables_hash
+ hash_table_t* databases_hash,
+ hash_table_t* tables_hash
)
{
const char* p;
@@ -3527,8 +3523,8 @@ xb_register_filter_entry(
strncpy(dbname, name, p - name);
dbname[p - name] = 0;
- if (*databases_hash) {
- HASH_SEARCH(name_hash, (*databases_hash),
+ if (databases_hash) {
+ HASH_SEARCH(name_hash, databases_hash,
ut_fold_string(dbname),
xb_filter_entry_t*,
db_entry, (void) 0,
@@ -3727,7 +3723,7 @@ xb_filter_hash_free(hash_table_t* hash)
ulint i;
/* free the hash elements */
- for (i = 0; i < hash_get_n_cells(hash); i++) {
+ for (i = 0; i < hash->n_cells; i++) {
xb_filter_entry_t* table;
table = static_cast<xb_filter_entry_t *>
@@ -3745,8 +3741,7 @@ xb_filter_hash_free(hash_table_t* hash)
}
}
- /* free hash */
- hash_table_free(hash);
+ hash->free();
}
static void xb_regex_list_free(regex_list_t* list)
@@ -3766,20 +3761,20 @@ xb_filters_free()
xb_regex_list_free(&regex_include_list);
xb_regex_list_free(&regex_exclude_list);
- if (tables_include_hash) {
- xb_filter_hash_free(tables_include_hash);
+ if (tables_include_hash.array) {
+ xb_filter_hash_free(&tables_include_hash);
}
- if (tables_exclude_hash) {
- xb_filter_hash_free(tables_exclude_hash);
+ if (tables_exclude_hash.array) {
+ xb_filter_hash_free(&tables_exclude_hash);
}
- if (databases_include_hash) {
- xb_filter_hash_free(databases_include_hash);
+ if (databases_include_hash.array) {
+ xb_filter_hash_free(&databases_include_hash);
}
- if (databases_exclude_hash) {
- xb_filter_hash_free(databases_exclude_hash);
+ if (databases_exclude_hash.array) {
+ xb_filter_hash_free(&databases_exclude_hash);
}
}
@@ -4644,7 +4639,7 @@ exit:
table->name = ((char*)table) + sizeof(xb_filter_entry_t);
strcpy(table->name, dest_space_name);
- HASH_INSERT(xb_filter_entry_t, name_hash, inc_dir_tables_hash,
+ HASH_INSERT(xb_filter_entry_t, name_hash, &inc_dir_tables_hash,
ut_fold_string(table->name), table);
mutex_enter(&fil_system.mutex);
@@ -5034,7 +5029,7 @@ rm_if_not_found(
/* Truncate ".ibd" */
name[strlen(name) - 4] = '\0';
- HASH_SEARCH(name_hash, inc_dir_tables_hash, ut_fold_string(name),
+ HASH_SEARCH(name_hash, &inc_dir_tables_hash, ut_fold_string(name),
xb_filter_entry_t*,
table, (void) 0,
!strcmp(table->name, name));
@@ -5410,7 +5405,7 @@ static bool xtrabackup_prepare_func(char** argv)
goto error_cleanup;
}
- inc_dir_tables_hash = hash_create(1000);
+ inc_dir_tables_hash.create(1000);
ok = xtrabackup_apply_deltas();
@@ -5423,7 +5418,7 @@ static bool xtrabackup_prepare_func(char** argv)
xb_process_datadir("./", ".ibd", rm_if_not_found);
}
- xb_filter_hash_free(inc_dir_tables_hash);
+ xb_filter_hash_free(&inc_dir_tables_hash);
fil_system.close();
#ifdef WITH_INNODB_DISALLOW_WRITES
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index ae5185e315e..b6ea78115e9 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -57,7 +57,6 @@ SET(INNOBASE_SOURCES
fsp/fsp0sysspace.cc
fut/fut0lst.cc
ha/ha0storage.cc
- ha/hash0hash.cc
fts/fts0fts.cc
fts/fts0ast.cc
fts/fts0blex.cc
@@ -163,7 +162,6 @@ SET(INNOBASE_SOURCES
include/ha0storage.ic
include/handler0alter.h
include/hash0hash.h
- include/hash0hash.ic
include/ib0mutex.h
include/ibuf0ibuf.h
include/ibuf0ibuf.ic
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index d9c99f59132..11104f078ff 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -3349,7 +3349,7 @@ btr_lift_page_up(
if (dict_index_is_spatial(index)) {
lock_mutex_enter();
lock_prdt_page_free_from_discard(
- block, lock_sys.prdt_page_hash);
+ block, &lock_sys.prdt_page_hash);
lock_mutex_exit();
}
lock_update_copy_and_discard(father_block, block);
@@ -3604,7 +3604,7 @@ retry:
/* No GAP lock needs to be worrying about */
lock_mutex_enter();
lock_prdt_page_free_from_discard(
- block, lock_sys.prdt_page_hash);
+ block, &lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
lock_mutex_exit();
} else {
@@ -3757,7 +3757,7 @@ retry:
}
lock_mutex_enter();
lock_prdt_page_free_from_discard(
- block, lock_sys.prdt_page_hash);
+ block, &lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
lock_mutex_exit();
} else {
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index bdaea6244ea..fbb4b36133b 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -492,8 +492,7 @@ static bool ha_insert_for_fold(hash_table_t *table, mem_heap_t* heap,
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
ut_ad(btr_search_enabled);
- ulint hash = hash_calc_hash(fold, table);
- hash_cell_t *cell= hash_get_nth_cell(table, hash);
+ hash_cell_t *cell= &table->array[table->calc_hash(fold)];
for (ha_node_t *prev= static_cast<ha_node_t*>(cell->node); prev;
prev= prev->next)
@@ -564,7 +563,7 @@ static void ha_delete_hash_node(hash_table_t *table, mem_heap_t *heap,
{
/* Compact the heap of nodes by moving the top in the place of del_node. */
*del_node= *top;
- hash_cell_t *cell= hash_get_nth_cell(table, table->calc_hash(top->fold));
+ hash_cell_t *cell= &table->array[table->calc_hash(top->fold)];
/* Look for the pointer to the top node, to update it */
if (cell->node == top)
@@ -2163,7 +2162,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
auto &part = btr_search_sys.parts[hash_table_id];
- cell_count = hash_get_n_cells(&part.table);
+ cell_count = part.table.n_cells;
for (i = 0; i < cell_count; i++) {
/* We release search latches every once in a while to
@@ -2184,7 +2183,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
mutex_enter(&buf_pool.mutex);
- ulint curr_cell_count = hash_get_n_cells(&part.table);
+ ulint curr_cell_count = part.table.n_cells;
if (cell_count != curr_cell_count) {
@@ -2196,7 +2195,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
}
}
- node = (ha_node_t*) hash_get_nth_cell(&part.table, i)->node;
+ node = static_cast<ha_node_t*>(part.table.array[i].node);
for (; node != NULL; node = node->next) {
const buf_block_t* block
@@ -2292,7 +2291,7 @@ state_ok:
mutex_enter(&buf_pool.mutex);
- ulint curr_cell_count = hash_get_n_cells(&part.table);
+ ulint curr_cell_count = part.table.n_cells;
if (cell_count != curr_cell_count) {
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index 854d8b13fd7..74d8476b8c9 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -359,7 +359,7 @@ buf_buddy_block_free(void* buf)
ut_ad(mutex_own(&buf_pool.mutex));
ut_a(!ut_align_offset(buf, srv_page_size));
- HASH_SEARCH(hash, buf_pool.zip_hash, fold, buf_page_t*, bpage,
+ HASH_SEARCH(hash, &buf_pool.zip_hash, fold, buf_page_t*, bpage,
ut_ad(bpage->state() == BUF_BLOCK_MEMORY
&& bpage->in_zip_hash),
((buf_block_t*) bpage)->frame == buf);
@@ -367,7 +367,7 @@ buf_buddy_block_free(void* buf)
ut_a(bpage->state() == BUF_BLOCK_MEMORY);
ut_ad(bpage->in_zip_hash);
ut_d(bpage->in_zip_hash = false);
- HASH_DELETE(buf_page_t, hash, buf_pool.zip_hash, fold, bpage);
+ HASH_DELETE(buf_page_t, hash, &buf_pool.zip_hash, fold, bpage);
ut_d(memset(buf, 0, srv_page_size));
UNIV_MEM_INVALID(buf, srv_page_size);
@@ -395,7 +395,7 @@ buf_buddy_block_register(
ut_ad(!block->page.in_zip_hash);
ut_d(block->page.in_zip_hash = true);
- HASH_INSERT(buf_page_t, hash, buf_pool.zip_hash, fold, &block->page);
+ HASH_INSERT(buf_page_t, hash, &buf_pool.zip_hash, fold, &block->page);
ut_d(buf_pool.buddy_n_frames++);
}
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 84e8bb0e1c6..44b8d912d24 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1523,11 +1523,11 @@ 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= hash_create(2 * curr_size);
+ page_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);
+ zip_hash.create(2 * curr_size);
last_printout_time= time(NULL);
mutex_create(LATCH_ID_FLUSH_LIST, &flush_list_mutex);
@@ -1606,8 +1606,8 @@ void buf_pool_t::close()
chunks= nullptr;
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);
+ page_hash.free();
+ zip_hash.free();
io_buf.close();
UT_DELETE(chunk_t::map_reg);
@@ -1683,7 +1683,7 @@ inline bool buf_pool_t::realloc(buf_block_t *block)
const ulint fold = id.fold();
ut_ad(&block->page == page_hash_get_low(id, fold));
ut_d(block->page.in_page_hash = false);
- HASH_REPLACE(buf_page_t, hash, page_hash, fold,
+ HASH_REPLACE(buf_page_t, hash, &page_hash, fold,
&block->page, &new_block->page);
buf_block_modify_clock_inc(block);
@@ -1924,44 +1924,46 @@ 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= hash_create(2 * buf_pool.curr_size);
+ hash_table_t new_hash;
+ new_hash.create(2 * buf_pool.curr_size);
- for (ulint i= 0; i < hash_get_n_cells(buf_pool.page_hash); i++)
+ for (ulint i= 0; i < buf_pool.page_hash.n_cells; i++)
{
while (buf_page_t *bpage= static_cast<buf_page_t*>
- (HASH_GET_FIRST(buf_pool.page_hash, i)))
+ (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);
+ HASH_DELETE(buf_page_t, hash, &buf_pool.page_hash, fold, prev_bpage);
+ HASH_INSERT(buf_page_t, hash, &new_hash, fold, 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);
+ std::swap(buf_pool.page_hash.array, new_hash.array);
+ buf_pool.page_hash.n_cells= new_hash.n_cells;
+ new_hash.free();
/* recreate zip_hash */
- new_hash_table= hash_create(2 * buf_pool.curr_size);
+ new_hash.create(2 * buf_pool.curr_size);
- for (ulint i= 0; i < hash_get_n_cells(buf_pool.zip_hash); i++)
+ for (ulint i= 0; i < buf_pool.zip_hash.n_cells; i++)
{
while (buf_page_t *bpage= static_cast<buf_page_t*>
- (HASH_GET_FIRST(buf_pool.zip_hash, i)))
+ (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_DELETE(buf_page_t, hash, &buf_pool.zip_hash, fold, prev_bpage);
+ HASH_INSERT(buf_page_t, hash, &new_hash, fold, prev_bpage);
}
}
- hash_table_free(buf_pool.zip_hash);
- buf_pool.zip_hash= new_hash_table;
+ std::swap(buf_pool.zip_hash.array, new_hash.array);
+ buf_pool.zip_hash.n_cells= new_hash.n_cells;
+ new_hash.free();
}
@@ -2430,7 +2432,7 @@ static void buf_relocate(buf_page_t *bpage, buf_page_t *dpage)
ut_ad(bpage->in_page_hash);
ut_ad(dpage->in_page_hash);
ut_d(bpage->in_page_hash= false);
- HASH_REPLACE(buf_page_t, hash, buf_pool.page_hash, fold, bpage, dpage);
+ HASH_REPLACE(buf_page_t, hash, &buf_pool.page_hash, fold, bpage, dpage);
}
/** Register a watch for a page identifier. The caller must hold an
@@ -2502,7 +2504,7 @@ retry:
w->buf_fix_count_= 1;
ut_ad(!w->in_page_hash);
ut_d(w->in_page_hash= true); /* Not holding buf_pool.mutex here! */
- HASH_INSERT(buf_page_t, hash, page_hash, fold, w);
+ HASH_INSERT(buf_page_t, hash, &page_hash, fold, w);
return nullptr;
}
@@ -3772,8 +3774,7 @@ buf_page_create(fil_space_t *space, uint32_t offset,
rw_lock_x_lock(hash_lock);
block->page.set_state(BUF_BLOCK_FILE_PAGE);
ut_d(block->page.in_page_hash= true);
- HASH_INSERT(buf_page_t, hash, buf_pool.page_hash, page_id.fold(),
- &block->page);
+ HASH_INSERT(buf_page_t, hash, &buf_pool.page_hash, fold, &block->page);
if (UNIV_UNLIKELY(zip_size))
{
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 06e268d3437..bc6e24a55de 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1239,7 +1239,7 @@ func_exit:
ut_ad(b->in_LRU_list);
ut_ad(b->in_page_hash);
- HASH_INSERT(buf_page_t, hash, buf_pool.page_hash, fold, b);
+ HASH_INSERT(buf_page_t, hash, &buf_pool.page_hash, fold, b);
/* Insert b where bpage was in the LRU list. */
if (prev_b) {
@@ -1488,7 +1488,7 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
}
ut_ad(!bpage->in_zip_hash);
- HASH_DELETE(buf_page_t, hash, buf_pool.page_hash, id.fold(), bpage);
+ HASH_DELETE(buf_page_t, hash, &buf_pool.page_hash, id.fold(), bpage);
switch (bpage->state()) {
case BUF_BLOCK_ZIP_PAGE:
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index 6e3221c94b4..0007e1d0831 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -59,7 +59,7 @@ inline void buf_pool_t::watch_remove(buf_page_t *watch)
{
ut_ad(watch->in_page_hash);
ut_d(watch->in_page_hash= false);
- HASH_DELETE(buf_page_t, hash, page_hash, watch->id().fold(), watch);
+ HASH_DELETE(buf_page_t, hash, &page_hash, watch->id().fold(), watch);
watch->set_buf_fix_count(0);
}
ut_ad(!watch->in_page_hash);
@@ -159,7 +159,7 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
block->page.set_state(BUF_BLOCK_FILE_PAGE);
ut_ad(!block->page.in_page_hash);
ut_d(block->page.in_page_hash= true);
- HASH_INSERT(buf_page_t, hash, buf_pool.page_hash, fold, bpage);
+ HASH_INSERT(buf_page_t, hash, &buf_pool.page_hash, fold, bpage);
rw_lock_x_unlock(hash_lock);
/* The block must be put to the LRU list, to the old blocks */
@@ -232,7 +232,7 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
ut_ad(!bpage->in_page_hash);
ut_d(bpage->in_page_hash= true);
- HASH_INSERT(buf_page_t, hash, buf_pool.page_hash, fold, bpage);
+ HASH_INSERT(buf_page_t, hash, &buf_pool.page_hash, fold, bpage);
bpage->set_io_fix(BUF_IO_READ);
rw_lock_x_unlock(hash_lock);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 0a20aacdef7..a3b8d025b10 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1034,9 +1034,9 @@ void dict_sys_t::create()
const ulint hash_size = buf_pool_get_curr_size()
/ (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE);
- table_hash= hash_create(hash_size);
- table_id_hash= hash_create(hash_size);
- temp_id_hash= hash_create(hash_size);
+ table_hash.create(hash_size);
+ table_id_hash.create(hash_size);
+ temp_id_hash.create(hash_size);
rw_lock_create(dict_operation_lock_key, &latch, SYNC_DICT_OPERATION);
@@ -1198,24 +1198,24 @@ inline void dict_sys_t::add(dict_table_t* table)
/* Look for a table with the same name: error if such exists */
{
dict_table_t* table2;
- HASH_SEARCH(name_hash, table_hash, fold,
+ HASH_SEARCH(name_hash, &table_hash, fold,
dict_table_t*, table2, ut_ad(table2->cached),
!strcmp(table2->name.m_name, table->name.m_name));
ut_a(table2 == NULL);
#ifdef UNIV_DEBUG
/* Look for the same table pointer with a different name */
- HASH_SEARCH_ALL(name_hash, table_hash,
+ HASH_SEARCH_ALL(name_hash, &table_hash,
dict_table_t*, table2, ut_ad(table2->cached),
table2 == table);
ut_ad(table2 == NULL);
#endif /* UNIV_DEBUG */
}
- HASH_INSERT(dict_table_t, name_hash, table_hash, fold, table);
+ HASH_INSERT(dict_table_t, name_hash, &table_hash, fold, table);
/* Look for a table with the same id: error if such exists */
hash_table_t* id_hash = table->is_temporary()
- ? temp_id_hash : table_id_hash;
+ ? &temp_id_hash : &table_id_hash;
const ulint id_fold = ut_fold_ull(table->id);
{
dict_table_t* table2;
@@ -1519,7 +1519,7 @@ dict_table_rename_in_cache(
/* Look for a table with the same name: error if such exists */
dict_table_t* table2;
- HASH_SEARCH(name_hash, dict_sys.table_hash, fold,
+ HASH_SEARCH(name_hash, &dict_sys.table_hash, fold,
dict_table_t*, table2, ut_ad(table2->cached),
(strcmp(table2->name.m_name, new_name) == 0));
DBUG_EXECUTE_IF("dict_table_rename_in_cache_failure",
@@ -1613,7 +1613,7 @@ dict_table_rename_in_cache(
}
/* Remove table from the hash tables of tables */
- HASH_DELETE(dict_table_t, name_hash, dict_sys.table_hash,
+ HASH_DELETE(dict_table_t, name_hash, &dict_sys.table_hash,
ut_fold_string(old_name), table);
if (strlen(new_name) > strlen(table->name.m_name)) {
@@ -1628,7 +1628,7 @@ dict_table_rename_in_cache(
strcpy(table->name.m_name, new_name);
/* Add table to hash table of tables */
- HASH_INSERT(dict_table_t, name_hash, dict_sys.table_hash, fold,
+ HASH_INSERT(dict_table_t, name_hash, &dict_sys.table_hash, fold,
table);
if (!rename_also_foreigns) {
@@ -1896,12 +1896,12 @@ dict_table_change_id_in_cache(
/* Remove the table from the hash table of id's */
- HASH_DELETE(dict_table_t, id_hash, dict_sys.table_id_hash,
+ HASH_DELETE(dict_table_t, id_hash, &dict_sys.table_id_hash,
ut_fold_ull(table->id), table);
table->id = new_id;
/* Add the table back to the hash table */
- HASH_INSERT(dict_table_t, id_hash, dict_sys.table_id_hash,
+ HASH_INSERT(dict_table_t, id_hash, &dict_sys.table_id_hash,
ut_fold_ull(table->id), table);
}
@@ -1946,11 +1946,11 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
/* Remove table from the hash tables of tables */
- HASH_DELETE(dict_table_t, name_hash, table_hash,
+ HASH_DELETE(dict_table_t, name_hash, &table_hash,
ut_fold_string(table->name.m_name), table);
hash_table_t* id_hash = table->is_temporary()
- ? temp_id_hash : table_id_hash;
+ ? &temp_id_hash : &table_id_hash;
const ulint id_fold = ut_fold_ull(table->id);
HASH_DELETE(dict_table_t, id_hash, id_hash, id_fold, table);
@@ -4880,38 +4880,39 @@ void dict_sys_t::resize()
mutex_enter(&mutex);
/* all table entries are in table_LRU and table_non_LRU lists */
- hash_table_free(table_hash);
- hash_table_free(table_id_hash);
- hash_table_free(temp_id_hash);
+ table_hash.free();
+ table_id_hash.free();
+ temp_id_hash.free();
const ulint hash_size = buf_pool_get_curr_size()
/ (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE);
- table_hash = hash_create(hash_size);
- table_id_hash = hash_create(hash_size);
- temp_id_hash = hash_create(hash_size);
+ table_hash.create(hash_size);
+ table_id_hash.create(hash_size);
+ temp_id_hash.create(hash_size);
- for (dict_table_t* table= UT_LIST_GET_FIRST(table_LRU); table;
+ for (dict_table_t *table= UT_LIST_GET_FIRST(table_LRU); table;
table= UT_LIST_GET_NEXT(table_LRU, table))
{
ut_ad(!table->is_temporary());
ulint fold= ut_fold_string(table->name.m_name);
ulint id_fold= ut_fold_ull(table->id);
- HASH_INSERT(dict_table_t, name_hash, table_hash, fold, table);
- HASH_INSERT(dict_table_t, id_hash, table_id_hash, id_fold, table);
+ HASH_INSERT(dict_table_t, name_hash, &table_hash, fold, table);
+ HASH_INSERT(dict_table_t, id_hash, &table_id_hash, id_fold, table);
}
- for (dict_table_t* table = UT_LIST_GET_FIRST(table_non_LRU); table;
- table = UT_LIST_GET_NEXT(table_LRU, table)) {
- ulint fold = ut_fold_string(table->name.m_name);
- ulint id_fold = ut_fold_ull(table->id);
+ for (dict_table_t *table = UT_LIST_GET_FIRST(table_non_LRU); table;
+ table= UT_LIST_GET_NEXT(table_LRU, table))
+ {
+ ulint fold= ut_fold_string(table->name.m_name);
+ ulint id_fold= ut_fold_ull(table->id);
- HASH_INSERT(dict_table_t, name_hash, table_hash, fold, table);
+ HASH_INSERT(dict_table_t, name_hash, &table_hash, fold, table);
- hash_table_t* id_hash = table->is_temporary()
- ? temp_id_hash : table_id_hash;
+ hash_table_t *id_hash= table->is_temporary()
+ ? &temp_id_hash : &table_id_hash;
- HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, table);
+ HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, table);
}
mutex_exit(&mutex);
@@ -4927,27 +4928,19 @@ void dict_sys_t::close()
/* Free the hash elements. We don't remove them from the table
because we are going to destroy the table anyway. */
- for (ulint i = 0; i < hash_get_n_cells(table_hash); i++)
- {
- dict_table_t* table = static_cast<dict_table_t*>(HASH_GET_FIRST(table_hash,
- i));
-
- while (table)
- {
- dict_table_t* prev_table = table;
- table = static_cast<dict_table_t*>(HASH_GET_NEXT(name_hash, prev_table));
- dict_sys.remove(prev_table);
- }
- }
+ for (ulint i= table_hash.n_cells; i--; )
+ while (dict_table_t *table= static_cast<dict_table_t*>
+ (HASH_GET_FIRST(&table_hash, i)))
+ dict_sys.remove(table);
- hash_table_free(table_hash);
+ table_hash.free();
/* table_id_hash contains the same elements as in table_hash,
therefore we don't delete the individual elements. */
- hash_table_free(table_id_hash);
+ table_id_hash.free();
/* No temporary tables should exist at this point. */
- hash_table_free(temp_id_hash);
+ temp_id_hash.free();
mutex_exit(&mutex);
mutex_free(&mutex);
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index e3fdc393564..2045df354b3 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -257,7 +257,7 @@ fil_space_get_by_id(
ut_ad(fil_system.is_initialised());
ut_ad(mutex_own(&fil_system.mutex));
- HASH_SEARCH(hash, fil_system.spaces, id,
+ HASH_SEARCH(hash, &fil_system.spaces, id,
fil_space_t*, space,
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
space->id == id);
@@ -987,7 +987,7 @@ std::vector<pfs_os_file_t> fil_system_t::detach(fil_space_t *space,
bool detach_handle)
{
ut_ad(mutex_own(&fil_system.mutex));
- HASH_DELETE(fil_space_t, hash, spaces, space->id, space);
+ HASH_DELETE(fil_space_t, hash, &spaces, space->id, space);
if (space->is_in_unflushed_spaces)
{
@@ -1210,7 +1210,7 @@ fil_space_create(
space->atomic_write_supported = true;
}
- HASH_INSERT(fil_space_t, hash, fil_system.spaces, id, space);
+ HASH_INSERT(fil_space_t, hash, &fil_system.spaces, id, space);
UT_LIST_ADD_LAST(fil_system.space_list, space);
@@ -1443,7 +1443,7 @@ void fil_system_t::create(ulint hash_size)
ut_ad(!is_initialised());
ut_ad(!(srv_page_size % FSP_EXTENT_SIZE));
ut_ad(srv_page_size);
- ut_ad(!spaces);
+ ut_ad(!spaces.array);
m_initialised = true;
@@ -1454,7 +1454,7 @@ void fil_system_t::create(ulint hash_size)
mutex_create(LATCH_ID_FIL_SYSTEM, &mutex);
- spaces = hash_create(hash_size);
+ spaces.create(hash_size);
fil_space_crypt_init();
#ifdef UNIV_LINUX
@@ -1530,13 +1530,12 @@ void fil_system_t::close()
if (is_initialised()) {
m_initialised = false;
- hash_table_free(spaces);
- spaces = NULL;
+ spaces.free();
mutex_free(&mutex);
fil_space_crypt_cleanup();
}
- ut_ad(!spaces);
+ ut_ad(!spaces.array);
}
/** Opens all system tablespace data files. They stay open until the
@@ -4183,10 +4182,10 @@ bool fil_validate()
/* Look for spaces in the hash table */
- for (ulint i = 0; i < hash_get_n_cells(fil_system.spaces); i++) {
+ for (ulint i = 0; i < fil_system.spaces.n_cells; i++) {
for (space = static_cast<fil_space_t*>(
- HASH_GET_FIRST(fil_system.spaces, i));
+ HASH_GET_FIRST(&fil_system.spaces, i));
space != 0;
space = static_cast<fil_space_t*>(
HASH_GET_NEXT(hash, space))) {
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 248a6753748..853db180277 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -1231,8 +1231,8 @@ rtr_check_discard_page(
mutex_exit(&index->rtr_track->rtr_active_mutex);
lock_mutex_enter();
- lock_prdt_page_free_from_discard(block, lock_sys.prdt_hash);
- lock_prdt_page_free_from_discard(block, lock_sys.prdt_page_hash);
+ lock_prdt_page_free_from_discard(block, &lock_sys.prdt_hash);
+ lock_prdt_page_free_from_discard(block, &lock_sys.prdt_page_hash);
lock_mutex_exit();
}
diff --git a/storage/innobase/ha/ha0storage.cc b/storage/innobase/ha/ha0storage.cc
index 8857b81f2d2..acde71b0557 100644
--- a/storage/innobase/ha/ha0storage.cc
+++ b/storage/innobase/ha/ha0storage.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -53,7 +54,7 @@ ha_storage_get(
HASH_SEARCH(
next, /* node->"next" */
- storage->hash, /* the hash table */
+ &storage->hash, /* the hash table */
fold, /* key */
ha_storage_node_t*, /* type of node->next */
node, /* auxiliary variable */
@@ -127,7 +128,7 @@ ha_storage_put_memlim(
HASH_INSERT(
ha_storage_node_t, /* type used in the hash chain */
next, /* node->"next" */
- storage->hash, /* the hash table */
+ &storage->hash, /* the hash table */
fold, /* key */
node); /* add this data to the hash */
diff --git a/storage/innobase/ha/hash0hash.cc b/storage/innobase/ha/hash0hash.cc
deleted file mode 100644
index 37e5bc4dea7..00000000000
--- a/storage/innobase/ha/hash0hash.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2020, MariaDB Corporation.
-
-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
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-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.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file ha/hash0hash.cc
-The simple hash table utility
-
-Created 5/20/1997 Heikki Tuuri
-*******************************************************/
-
-#include "hash0hash.h"
-#include "mem0mem.h"
-#include "sync0sync.h"
-
-/** Create the hash table.
-@param n the lower bound of n_cells */
-void hash_table_t::create(ulint n)
-{
- n_cells= ut_find_prime(n);
- array= static_cast<hash_cell_t*>(ut_zalloc_nokey(n_cells * sizeof *array));
-}
-
-/**
-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_table_t *table= static_cast<hash_table_t*>
- (ut_zalloc_nokey(sizeof *table));
- table->create(n);
- return table;
-}
-
-/*************************************************************//**
-Frees a hash table. */
-void
-hash_table_free(
-/*============*/
- hash_table_t* table) /*!< in, own: hash table */
-{
- ut_free(table->array);
- ut_free(table);
-}
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 6758e427c74..96c96113e85 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1613,7 +1613,7 @@ public:
rw_lock_t *hash_lock_get_low(ulint fold) const
{
return page_hash_latches +
- ut_2pow_remainder(page_hash->calc_hash(fold),
+ ut_2pow_remainder(page_hash.calc_hash(fold),
ulint{srv_n_page_hash_locks});
}
private:
@@ -1633,13 +1633,13 @@ public:
{
for (;;)
{
- auto n_cells= page_hash->n_cells;
+ auto n_cells= page_hash.n_cells;
rw_lock_t *latch= hash_lock_get_low(fold, n_cells);
if (exclusive)
rw_lock_x_lock(latch);
else
rw_lock_s_lock(latch);
- if (UNIV_LIKELY(n_cells == page_hash->n_cells))
+ if (UNIV_LIKELY(n_cells == page_hash.n_cells))
return latch;
if (exclusive)
rw_lock_x_unlock(latch);
@@ -1661,7 +1661,7 @@ public:
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
buf_page_t *bpage;
/* Look for the page in the hash table */
- HASH_SEARCH(hash, page_hash, fold, buf_page_t*, bpage,
+ HASH_SEARCH(hash, &page_hash, fold, buf_page_t*, bpage,
ut_ad(bpage->in_page_hash), id == bpage->id());
return bpage;
}
@@ -1785,7 +1785,7 @@ public:
/* The following is based on watch_remove(). */
ut_ad(watch->in_page_hash);
ut_d(watch->in_page_hash= false);
- HASH_DELETE(buf_page_t, hash, page_hash, fold, watch);
+ HASH_DELETE(buf_page_t, hash, &page_hash, fold, watch);
rw_lock_x_unlock(hash_lock);
// Now that the watch is detached from page_hash, release it to watch[].
mutex_enter(&mutex);
@@ -1874,15 +1874,13 @@ public:
/** Hash table of file pages (buf_page_t::in_file() holds),
indexed by page_id_t. Protected by both mutex and page_hash_latches[]. */
- hash_table_t *page_hash;
+ hash_table_t page_hash;
/** 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,
- indexed by block->frame;
- protected by buf_pool.mutex*/
+ /** map of block->frame to buf_block_t blocks that belong
+ to buf_buddy_alloc(); protected by buf_pool.mutex */
+ hash_table_t zip_hash;
/** number of pending read operations */
Atomic_counter<ulint> n_pend_reads;
Atomic_counter<ulint>
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 92f7435ab6d..2a153f448e9 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1432,10 +1432,10 @@ public:
header and flushed to a file; in
recovery this must be derived from
the log records */
- hash_table_t* table_hash; /*!< hash table of the tables, based
+ hash_table_t table_hash; /*!< hash table of the tables, based
on name */
/** hash table of persistent table IDs */
- hash_table_t* table_id_hash;
+ hash_table_t table_id_hash;
dict_table_t* sys_tables; /*!< SYS_TABLES table */
dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
@@ -1454,7 +1454,7 @@ private:
/** the sequence of temporary table IDs */
std::atomic<table_id_t> temp_table_id;
/** hash table of temporary table IDs */
- hash_table_t* temp_id_hash;
+ hash_table_t temp_id_hash;
public:
/** @return a new temporary table ID */
table_id_t get_temporary_table_id() {
@@ -1471,7 +1471,7 @@ public:
ut_ad(mutex_own(&mutex));
dict_table_t* table;
ulint fold = ut_fold_ull(id);
- HASH_SEARCH(id_hash, temp_id_hash, fold, dict_table_t*, table,
+ HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
ut_ad(table->cached), table->id == id);
if (UNIV_LIKELY(table != NULL)) {
DBUG_ASSERT(table->is_temporary());
@@ -1490,7 +1490,8 @@ public:
ut_ad(mutex_own(&mutex));
dict_table_t* table;
ulint fold = ut_fold_ull(id);
- HASH_SEARCH(id_hash, table_id_hash, fold, dict_table_t*, table,
+ HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*,
+ table,
ut_ad(table->cached), table->id == id);
DBUG_ASSERT(!table || !table->is_temporary());
return table;
@@ -1592,8 +1593,8 @@ public:
+ (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10
+ sizeof(dict_field_t) * 5 /* total number of key fields */
+ 200; /* arbitrary, covering names and overhead */
- size += (table_hash->n_cells + table_id_hash->n_cells
- + temp_id_hash->n_cells) * sizeof(hash_cell_t);
+ size += (table_hash.n_cells + table_id_hash.n_cells
+ + temp_id_hash.n_cells) * sizeof(hash_cell_t);
return size;
}
};
diff --git a/storage/innobase/include/dict0priv.ic b/storage/innobase/include/dict0priv.ic
index ff645378175..2fcadc055e1 100644
--- a/storage/innobase/include/dict0priv.ic
+++ b/storage/innobase/include/dict0priv.ic
@@ -84,7 +84,7 @@ dict_table_check_if_in_cache_low(
/* Look for the table name in the hash table */
table_fold = ut_fold_string(table_name);
- HASH_SEARCH(name_hash, dict_sys.table_hash, table_fold,
+ HASH_SEARCH(name_hash, &dict_sys.table_hash, table_fold,
dict_table_t*, table, ut_ad(table->cached),
!strcmp(table->name.m_name, table_name));
DBUG_RETURN(table);
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 5dbf5e99400..7d0402574d6 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1217,9 +1217,8 @@ public:
ib_mutex_t mutex; /*!< The mutex protecting the cache */
fil_space_t* sys_space; /*!< The innodb_system tablespace */
fil_space_t* temp_space; /*!< The innodb_temporary tablespace */
- hash_table_t* spaces; /*!< The hash table of spaces in the
- system; they are hashed on the space
- id */
+ /** Map of fil_space_t::id to fil_space_t* */
+ hash_table_t spaces;
UT_LIST_BASE_NODE_T(fil_node_t) LRU;
/*!< base node for the LRU list of the
most recently used open files with no
diff --git a/storage/innobase/include/ha0ha.ic b/storage/innobase/include/ha0ha.ic
index e358b1070eb..0b256257214 100644
--- a/storage/innobase/include/ha0ha.ic
+++ b/storage/innobase/include/ha0ha.ic
@@ -93,8 +93,7 @@ ha_chain_get_first(
hash_table_t* table, /*!< in: hash table */
ulint fold) /*!< in: fold value determining the chain */
{
- return((ha_node_t*)
- hash_get_nth_cell(table, hash_calc_hash(fold, table))->node);
+ return static_cast<ha_node_t*>(table->array[table->calc_hash(fold)].node);
}
/*************************************************************//**
diff --git a/storage/innobase/include/ha0storage.ic b/storage/innobase/include/ha0storage.ic
index 8cc487faf47..df9679cf997 100644
--- a/storage/innobase/include/ha0storage.ic
+++ b/storage/innobase/include/ha0storage.ic
@@ -32,7 +32,7 @@ Created September 24, 2007 Vasil Dimov
struct ha_storage_t {
mem_heap_t* heap; /*!< memory heap from which memory is
allocated */
- hash_table_t* hash; /*!< hash table used to avoid
+ hash_table_t hash; /*!< hash table used to avoid
duplicates */
};
@@ -77,7 +77,7 @@ ha_storage_create(
sizeof(ha_storage_t));
storage->heap = heap;
- storage->hash = hash_create(initial_hash_cells);
+ storage->hash.create(initial_hash_cells);
return(storage);
}
@@ -97,7 +97,7 @@ ha_storage_empty(
temp_storage.heap = (*storage)->heap;
temp_storage.hash = (*storage)->hash;
- hash_table_clear(temp_storage.hash);
+ temp_storage.hash.clear();
mem_heap_empty(temp_storage.heap);
*storage = (ha_storage_t*) mem_heap_alloc(temp_storage.heap,
@@ -117,9 +117,7 @@ ha_storage_free(
/*============*/
ha_storage_t* storage) /*!< in, own: hash storage */
{
- /* order is important because the pointer storage->hash is
- within the heap */
- hash_table_free(storage->hash);
+ storage->hash.free();
mem_heap_free(storage->heap);
}
@@ -138,7 +136,7 @@ ha_storage_get_size(
/* this assumes hash->heap and hash->heaps are NULL */
ret += sizeof(hash_table_t);
- ret += sizeof(hash_cell_t) * hash_get_n_cells(storage->hash);
+ ret += sizeof(hash_cell_t) * storage->hash.n_cells;
return(ret);
}
diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
index 8d84e6e976c..58da36fee5e 100644
--- a/storage/innobase/include/hash0hash.h
+++ b/storage/innobase/include/hash0hash.h
@@ -33,22 +33,6 @@ struct hash_cell_t{
};
typedef void* hash_node_t;
-/* Fix Bug #13859: symbol collision between imap/mysql */
-#define hash_create hash0_create
-
-/**
-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. */
-void
-hash_table_free(
-/*============*/
- hash_table_t* table); /*!< in, own: hash table */
-
#define hash_calc_hash(FOLD, TABLE) (TABLE)->calc_hash(FOLD)
/*******************************************************************//**
@@ -61,7 +45,7 @@ do {\
\
(DATA)->NAME = NULL;\
\
- cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
+ cell3333 = &(TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
\
if (cell3333->node == NULL) {\
cell3333->node = DATA;\
@@ -87,7 +71,7 @@ do { \
\
(DATA)->NAME = NULL; \
\
- cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
+ cell3333 = &(TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
\
if (cell3333->node == NULL) { \
cell3333->node = DATA; \
@@ -116,7 +100,7 @@ do {\
hash_cell_t* cell3333;\
TYPE* struct3333;\
\
- cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
+ cell3333 = &(TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
\
if (cell3333->node == DATA) {\
HASH_ASSERT_VALID(DATA->NAME);\
@@ -140,7 +124,7 @@ do {\
(DATA_NEW)->NAME = (DATA_OLD)->NAME; \
\
hash_cell_t& cell3333 \
- = TABLE->array[hash_calc_hash(FOLD, TABLE)]; \
+ = (TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
TYPE** struct3333 = (TYPE**)&cell3333.node; \
while (*struct3333 != DATA_OLD) { \
struct3333 = &((*struct3333)->NAME); \
@@ -150,8 +134,7 @@ do {\
/*******************************************************************//**
Gets the first struct in a hash chain, NULL if none. */
-#define HASH_GET_FIRST(TABLE, HASH_VAL)\
- (hash_get_nth_cell(TABLE, HASH_VAL)->node)
+#define HASH_GET_FIRST(TABLE, HASH_VAL) (TABLE)->array[HASH_VAL].node
/*******************************************************************//**
Gets the next struct in a hash chain, NULL if none. */
@@ -202,33 +185,6 @@ do { \
} \
} while (0)
-/************************************************************//**
-Gets the nth cell in a hash table.
-@return pointer to cell */
-UNIV_INLINE
-hash_cell_t*
-hash_get_nth_cell(
-/*==============*/
- hash_table_t* table, /*!< in: hash table */
- ulint n); /*!< in: cell index */
-
-/*************************************************************//**
-Clears a hash table so that all the cells become empty. */
-UNIV_INLINE
-void
-hash_table_clear(
-/*=============*/
- hash_table_t* table); /*!< in/out: hash table */
-
-/*************************************************************//**
-Returns the number of cells in a hash table.
-@return number of cells */
-UNIV_INLINE
-ulint
-hash_get_n_cells(
-/*=============*/
- hash_table_t* table); /*!< in: table */
-
/****************************************************************//**
Move all hash table entries from OLD_TABLE to NEW_TABLE. */
@@ -237,7 +193,7 @@ do {\
ulint i2222;\
ulint cell_count2222;\
\
- cell_count2222 = hash_get_n_cells(OLD_TABLE);\
+ cell_count2222 = (OLD_TABLE)->n_cells; \
\
for (i2222 = 0; i2222 < cell_count2222; i2222++) {\
NODE_TYPE* node2222 = static_cast<NODE_TYPE*>(\
@@ -256,7 +212,7 @@ do {\
}\
} while (0)
-/** Hash table with singly-linkde overflow lists */
+/** Hash table with singly-linked overflow lists */
struct hash_table_t
{
/** number of elements in array (a prime number) */
@@ -266,9 +222,17 @@ struct hash_table_t
/** Create the hash table.
@param n the lower bound of n_cells */
- void create(ulint n);
+ void create(ulint n)
+ {
+ n_cells= ut_find_prime(n);
+ array= static_cast<hash_cell_t*>(ut_zalloc_nokey(n_cells * sizeof *array));
+ }
+
+ /** Clear the hash table. */
+ void clear() { memset(array, 0, n_cells * sizeof *array); }
+
+ /** Free the hash table. */
+ void free() { ut_free(array); array= nullptr; }
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
deleted file mode 100644
index e6ca3b15bd0..00000000000
--- a/storage/innobase/include/hash0hash.ic
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2020, MariaDB Corporation.
-
-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
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-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.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/hash0hash.ic
-The simple hash table utility
-
-Created 5/20/1997 Heikki Tuuri
-*******************************************************/
-
-/************************************************************//**
-Gets the nth cell in a hash table.
-@return pointer to cell */
-UNIV_INLINE
-hash_cell_t*
-hash_get_nth_cell(
-/*==============*/
- hash_table_t* table, /*!< in: hash table */
- ulint n) /*!< in: cell index */
-{
- ut_ad(table);
- ut_ad(n < table->n_cells);
-
- return(table->array + n);
-}
-
-/*************************************************************//**
-Clears a hash table so that all the cells become empty. */
-UNIV_INLINE
-void
-hash_table_clear(
-/*=============*/
- hash_table_t* table) /*!< in/out: hash table */
-{
- ut_ad(table);
- memset(table->array, 0x0,
- table->n_cells * sizeof(*table->array));
-}
-
-/*************************************************************//**
-Returns the number of cells in a hash table.
-@return number of cells */
-UNIV_INLINE
-ulint
-hash_get_n_cells(
-/*=============*/
- hash_table_t* table) /*!< in: table */
-{
- ut_ad(table);
- return(table->n_cells);
-}
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 9faf12f13a3..ab697a730d2 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -759,12 +759,12 @@ public:
MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex mutex; /*!< Mutex protecting the
locks */
- hash_table_t* rec_hash; /*!< hash table of the record
- locks */
- hash_table_t* prdt_hash; /*!< hash table of the predicate
- lock */
- hash_table_t* prdt_page_hash; /*!< hash table of the page
- lock */
+ /** record locks */
+ hash_table_t rec_hash;
+ /** predicate locks for SPATIAL INDEX */
+ hash_table_t prdt_hash;
+ /** page locks for SPATIAL INDEX */
+ hash_table_t prdt_page_hash;
MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex wait_mutex; /*!< Mutex protecting the
diff --git a/storage/innobase/include/lock0lock.ic b/storage/innobase/include/lock0lock.ic
index a01d866e6c0..6146f835be9 100644
--- a/storage/innobase/include/lock0lock.ic
+++ b/storage/innobase/include/lock0lock.ic
@@ -53,8 +53,7 @@ lock_rec_hash(
ulint space, /*!< in: space */
ulint page_no)/*!< in: page number */
{
- return(unsigned(hash_calc_hash(lock_rec_fold(space, page_no),
- lock_sys.rec_hash)));
+ return unsigned(lock_sys.rec_hash.calc_hash(lock_rec_fold(space, page_no)));
}
/*********************************************************************//**
@@ -90,11 +89,11 @@ lock_hash_get(
ulint mode) /*!< in: lock mode */
{
if (mode & LOCK_PREDICATE) {
- return(lock_sys.prdt_hash);
+ return &lock_sys.prdt_hash;
} else if (mode & LOCK_PRDT_PAGE) {
- return(lock_sys.prdt_page_hash);
+ return &lock_sys.prdt_page_hash;
} else {
- return(lock_sys.rec_hash);
+ return &lock_sys.rec_hash;
}
}
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index f11a2a35750..1ea39da6c4d 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -463,9 +463,9 @@ void lock_sys_t::create(ulint n_cells)
mutex_create(LATCH_ID_LOCK_SYS_WAIT, &wait_mutex);
- rec_hash = hash_create(n_cells);
- prdt_hash = hash_create(n_cells);
- prdt_page_hash = hash_create(n_cells);
+ rec_hash.create(n_cells);
+ prdt_hash.create(n_cells);
+ prdt_page_hash.create(n_cells);
if (!srv_read_only_mode) {
lock_latest_err_file = os_file_create_tmpfile();
@@ -498,23 +498,23 @@ void lock_sys_t::resize(ulint n_cells)
mutex_enter(&mutex);
- hash_table_t* old_hash = rec_hash;
- rec_hash = hash_create(n_cells);
- HASH_MIGRATE(old_hash, rec_hash, lock_t, hash,
+ hash_table_t old_hash(rec_hash);
+ rec_hash.create(n_cells);
+ HASH_MIGRATE(&old_hash, &rec_hash, lock_t, hash,
lock_rec_lock_fold);
- hash_table_free(old_hash);
+ old_hash.free();
old_hash = prdt_hash;
- prdt_hash = hash_create(n_cells);
- HASH_MIGRATE(old_hash, prdt_hash, lock_t, hash,
+ prdt_hash.create(n_cells);
+ HASH_MIGRATE(&old_hash, &prdt_hash, lock_t, hash,
lock_rec_lock_fold);
- hash_table_free(old_hash);
+ old_hash.free();
old_hash = prdt_page_hash;
- prdt_page_hash = hash_create(n_cells);
- HASH_MIGRATE(old_hash, prdt_page_hash, lock_t, hash,
+ prdt_page_hash.create(n_cells);
+ HASH_MIGRATE(&old_hash, &prdt_page_hash, lock_t, hash,
lock_rec_lock_fold);
- hash_table_free(old_hash);
+ old_hash.free();
/* need to update block->lock_hash_val */
mutex_enter(&buf_pool.mutex);
@@ -543,9 +543,9 @@ void lock_sys_t::close()
lock_latest_err_file = NULL;
}
- hash_table_free(rec_hash);
- hash_table_free(prdt_hash);
- hash_table_free(prdt_page_hash);
+ rec_hash.free();
+ prdt_hash.free();
+ prdt_page_hash.free();
mutex_destroy(&mutex);
mutex_destroy(&wait_mutex);
@@ -871,7 +871,7 @@ lock_rec_expl_exist_on_page(
lock_mutex_enter();
/* Only used in ibuf pages, so rec_hash is good enough */
- lock = lock_rec_get_first_on_page_addr(lock_sys.rec_hash,
+ lock = lock_rec_get_first_on_page_addr(&lock_sys.rec_hash,
space, page_no);
lock_mutex_exit();
@@ -989,7 +989,7 @@ lock_rec_has_expl(
|| (precise_mode & LOCK_MODE_MASK) == LOCK_X);
ut_ad(!(precise_mode & LOCK_INSERT_INTENTION));
- for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -1042,8 +1042,8 @@ lock_rec_other_has_expl_req(
return(NULL);
}
- for (lock_t* lock = lock_rec_get_first(lock_sys.rec_hash,
- block, heap_no);
+ for (lock_t* lock = lock_rec_get_first(&lock_sys.rec_hash,
+ block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -1148,7 +1148,7 @@ lock_rec_other_has_conflicting(
bool is_supremum = (heap_no == PAGE_HEAP_NO_SUPREMUM);
- for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -1468,7 +1468,7 @@ lock_rec_create_low(
&& innodb_lock_schedule_algorithm
== INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&& !thd_is_replication_slave_thread(trx->mysql_thd)) {
- HASH_PREPEND(lock_t, hash, lock_sys.rec_hash,
+ HASH_PREPEND(lock_t, hash, &lock_sys.rec_hash,
lock_rec_fold(space, page_no), lock);
} else {
HASH_INSERT(lock_t, hash, lock_hash_get(type_mode),
@@ -1538,8 +1538,7 @@ lock_rec_insert_by_trx_age(
page_no = in_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no);
hash = lock_hash_get(in_lock->type_mode);
- cell = hash_get_nth_cell(hash,
- hash_calc_hash(rec_fold, hash));
+ cell = &hash->array[hash->calc_hash(rec_fold)];
node = (lock_t *) cell->node;
// If in_lock is not a wait lock, we insert it to the head of the list.
@@ -1597,8 +1596,7 @@ lock_queue_validate(
page_no = in_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no);
hash = lock_hash_get(in_lock->type_mode);
- cell = hash_get_nth_cell(hash,
- hash_calc_hash(rec_fold, hash));
+ cell = &hash->array[hash->calc_hash(rec_fold)];
next = (lock_t *) cell->node;
while (next != NULL) {
// If this is a granted lock, check that there's no wait lock before it.
@@ -1628,8 +1626,7 @@ lock_rec_insert_to_head(
}
hash = lock_hash_get(in_lock->type_mode);
- cell = hash_get_nth_cell(hash,
- hash_calc_hash(rec_fold, hash));
+ cell = &hash->array[hash->calc_hash(rec_fold)];
node = (lock_t *) cell->node;
if (node != in_lock) {
cell->node = in_lock;
@@ -1745,7 +1742,7 @@ lock_rec_enqueue_waiting(
== INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&& !prdt
&& !thd_is_replication_slave_thread(lock->trx->mysql_thd)) {
- HASH_DELETE(lock_t, hash, lock_sys.rec_hash,
+ HASH_DELETE(lock_t, hash, &lock_sys.rec_hash,
lock_rec_lock_fold(lock), lock);
dberr_t res = lock_rec_insert_by_trx_age(lock);
if (res != DB_SUCCESS) {
@@ -1928,7 +1925,7 @@ lock_rec_lock(
if (lock_table_has(trx, index->table,
static_cast<lock_mode>(LOCK_MODE_MASK & mode)));
- else if (lock_t *lock= lock_rec_get_first_on_page(lock_sys.rec_hash, block))
+ else if (lock_t *lock= lock_rec_get_first_on_page(&lock_sys.rec_hash, block))
{
trx_mutex_enter(trx);
if (lock_rec_get_next_on_page(lock) ||
@@ -2151,9 +2148,8 @@ lock_grant_and_move_on_page(ulint rec_fold, ulint space, ulint page_no)
{
lock_t* lock;
lock_t* previous = static_cast<lock_t*>(
- hash_get_nth_cell(lock_sys.rec_hash,
- hash_calc_hash(rec_fold, lock_sys.rec_hash))
- ->node);
+ lock_sys.rec_hash.array[lock_sys.rec_hash.calc_hash(rec_fold)].
+ node);
if (previous == NULL) {
return;
}
@@ -2229,7 +2225,7 @@ static void lock_rec_dequeue_from_page(lock_t* in_lock)
if (innodb_lock_schedule_algorithm
== INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
- || lock_hash != lock_sys.rec_hash
+ || lock_hash != &lock_sys.rec_hash
|| thd_is_replication_slave_thread(in_lock->trx->mysql_thd)) {
/* Check if waiting locks in the queue can now be granted:
grant locks if there are no conflicting locks ahead. Stop at
@@ -2331,11 +2327,11 @@ lock_rec_free_all_from_discard_page(
page_no = block->page.id().page_no();
lock_rec_free_all_from_discard_page_low(
- space, page_no, lock_sys.rec_hash);
+ space, page_no, &lock_sys.rec_hash);
lock_rec_free_all_from_discard_page_low(
- space, page_no, lock_sys.prdt_hash);
+ space, page_no, &lock_sys.prdt_hash);
lock_rec_free_all_from_discard_page_low(
- space, page_no, lock_sys.prdt_page_hash);
+ space, page_no, &lock_sys.prdt_page_hash);
}
/*============= RECORD LOCK MOVING AND INHERITING ===================*/
@@ -2380,12 +2376,12 @@ lock_rec_reset_and_release_wait(
ulint heap_no)/*!< in: heap number of record */
{
lock_rec_reset_and_release_wait_low(
- lock_sys.rec_hash, block, heap_no);
+ &lock_sys.rec_hash, block, heap_no);
lock_rec_reset_and_release_wait_low(
- lock_sys.prdt_hash, block, PAGE_HEAP_NO_INFIMUM);
+ &lock_sys.prdt_hash, block, PAGE_HEAP_NO_INFIMUM);
lock_rec_reset_and_release_wait_low(
- lock_sys.prdt_page_hash, block, PAGE_HEAP_NO_INFIMUM);
+ &lock_sys.prdt_page_hash, block, PAGE_HEAP_NO_INFIMUM);
}
/*************************************************************//**
@@ -2418,7 +2414,7 @@ lock_rec_inherit_to_gap(
DO want S-locks/X-locks(taken for replace) set by a consistency
constraint to be inherited also then. */
- for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -2454,7 +2450,7 @@ lock_rec_inherit_to_gap_if_gap_lock(
lock_mutex_enter();
- for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) {
@@ -2498,8 +2494,8 @@ lock_rec_move_low(
/* If the lock is predicate lock, it resides on INFIMUM record */
ut_ad(lock_rec_get_first(
lock_hash, receiver, receiver_heap_no) == NULL
- || lock_hash == lock_sys.prdt_hash
- || lock_hash == lock_sys.prdt_page_hash);
+ || lock_hash == &lock_sys.prdt_hash
+ || lock_hash == &lock_sys.prdt_page_hash);
for (lock = lock_rec_get_first(lock_hash,
donator, donator_heap_no);
@@ -2522,8 +2518,8 @@ lock_rec_move_low(
lock->index, lock->trx, FALSE);
}
- ut_ad(lock_rec_get_first(lock_sys.rec_hash,
- donator, donator_heap_no) == NULL);
+ ut_ad(!lock_rec_get_first(&lock_sys.rec_hash,
+ donator, donator_heap_no));
}
/** Move all the granted locks to the front of the given lock list.
@@ -2577,7 +2573,7 @@ lock_rec_move(
ulint donator_heap_no)/*!< in: heap_no of the record
which gives the locks */
{
- lock_rec_move_low(lock_sys.rec_hash, receiver, donator,
+ lock_rec_move_low(&lock_sys.rec_hash, receiver, donator,
receiver_heap_no, donator_heap_no);
}
@@ -2602,7 +2598,7 @@ lock_move_reorganize_page(
lock_mutex_enter();
/* FIXME: This needs to deal with predicate lock too */
- lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block);
+ lock = lock_rec_get_first_on_page(&lock_sys.rec_hash, block);
if (lock == NULL) {
lock_mutex_exit();
@@ -2735,7 +2731,8 @@ lock_move_rec_list_end(
table to the end of the hash chain, and lock_rec_add_to_queue
does not reuse locks if there are waiters in the queue. */
- for (lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block); lock;
+ for (lock = lock_rec_get_first_on_page(&lock_sys.rec_hash, block);
+ lock;
lock = lock_rec_get_next_on_page(lock)) {
const rec_t* rec1 = rec;
const rec_t* rec2;
@@ -2850,7 +2847,8 @@ lock_move_rec_list_start(
lock_mutex_enter();
- for (lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block); lock;
+ for (lock = lock_rec_get_first_on_page(&lock_sys.rec_hash, block);
+ lock;
lock = lock_rec_get_next_on_page(lock)) {
const rec_t* rec1;
const rec_t* rec2;
@@ -2962,7 +2960,8 @@ lock_rtr_move_rec_list(
lock_mutex_enter();
- for (lock = lock_rec_get_first_on_page(lock_sys.rec_hash, block); lock;
+ for (lock = lock_rec_get_first_on_page(&lock_sys.rec_hash, block);
+ lock;
lock = lock_rec_get_next_on_page(lock)) {
ulint moved = 0;
const rec_t* rec1;
@@ -3074,12 +3073,12 @@ lock_update_merge_right(
waiting transactions */
lock_rec_reset_and_release_wait_low(
- lock_sys.rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
+ &lock_sys.rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
/* there should exist no page lock on the left page,
otherwise, it will be blocked from merge */
ut_ad(!lock_rec_get_first_on_page_addr(
- lock_sys.prdt_page_hash,
+ &lock_sys.prdt_page_hash,
left_block->page.id().space(),
left_block->page.id().page_no()));
@@ -3189,7 +3188,7 @@ lock_update_merge_left(
releasing waiting transactions */
lock_rec_reset_and_release_wait_low(
- lock_sys.rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
+ &lock_sys.rec_hash, left_block, PAGE_HEAP_NO_SUPREMUM);
}
/* Move the locks from the supremum of right page to the supremum
@@ -3201,7 +3200,7 @@ lock_update_merge_left(
/* there should exist no page lock on the right page,
otherwise, it will be blocked from merge */
ut_ad(!lock_rec_get_first_on_page_addr(
- lock_sys.prdt_page_hash,
+ &lock_sys.prdt_page_hash,
right_block->page.id().space(),
right_block->page.id().page_no()));
@@ -3254,9 +3253,9 @@ lock_update_discard(
lock_mutex_enter();
- if (lock_rec_get_first_on_page(lock_sys.rec_hash, block)) {
- ut_ad(!lock_rec_get_first_on_page(lock_sys.prdt_hash, block));
- ut_ad(!lock_rec_get_first_on_page(lock_sys.prdt_page_hash,
+ if (lock_rec_get_first_on_page(&lock_sys.rec_hash, block)) {
+ ut_ad(!lock_rec_get_first_on_page(&lock_sys.prdt_hash, block));
+ ut_ad(!lock_rec_get_first_on_page(&lock_sys.prdt_page_hash,
block));
/* Inherit all the locks on the page to the record and
reset all the locks on the page */
@@ -3293,14 +3292,14 @@ lock_update_discard(
lock_rec_free_all_from_discard_page_low(
block->page.id().space(), block->page.id().page_no(),
- lock_sys.rec_hash);
+ &lock_sys.rec_hash);
} else {
lock_rec_free_all_from_discard_page_low(
block->page.id().space(), block->page.id().page_no(),
- lock_sys.prdt_hash);
+ &lock_sys.prdt_hash);
lock_rec_free_all_from_discard_page_low(
block->page.id().space(), block->page.id().page_no(),
- lock_sys.prdt_page_hash);
+ &lock_sys.prdt_page_hash);
}
lock_mutex_exit();
@@ -4068,12 +4067,10 @@ run_again:
static
void
lock_grant_and_move_on_rec(
- hash_table_t* lock_hash,
lock_t* first_lock,
ulint heap_no)
{
lock_t* lock;
- lock_t* previous;
ulint space;
ulint page_no;
ulint rec_fold;
@@ -4082,8 +4079,9 @@ lock_grant_and_move_on_rec(
page_no = first_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no);
- previous = (lock_t *) hash_get_nth_cell(lock_hash,
- hash_calc_hash(rec_fold, lock_hash))->node;
+ lock_t* previous = static_cast<lock_t*>(
+ lock_sys.rec_hash.array[lock_sys.rec_hash.calc_hash(rec_fold)]
+ .node);
if (previous == NULL) {
return;
}
@@ -4155,7 +4153,7 @@ lock_rec_unlock(
lock_mutex_enter();
trx_mutex_enter(trx);
- first_lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ first_lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
/* Find the last lock with the same lock_mode and transaction
on the record. */
@@ -4204,7 +4202,7 @@ released:
}
}
} else {
- lock_grant_and_move_on_rec(lock_sys.rec_hash, first_lock, heap_no);
+ lock_grant_and_move_on_rec(first_lock, heap_no);
}
lock_mutex_exit();
@@ -4501,21 +4499,18 @@ http://bugs.mysql.com/36942 */
/*********************************************************************//**
Calculates the number of record lock structs in the record lock hash table.
@return number of record locks */
-static
-ulint
-lock_get_n_rec_locks(void)
-/*======================*/
+static ulint lock_get_n_rec_locks()
{
ulint n_locks = 0;
ulint i;
ut_ad(lock_mutex_own());
- for (i = 0; i < hash_get_n_cells(lock_sys.rec_hash); i++) {
+ for (i = 0; i < lock_sys.rec_hash.n_cells; i++) {
const lock_t* lock;
for (lock = static_cast<const lock_t*>(
- HASH_GET_FIRST(lock_sys.rec_hash, i));
+ HASH_GET_FIRST(&lock_sys.rec_hash, i));
lock != 0;
lock = static_cast<const lock_t*>(
HASH_GET_NEXT(hash, lock))) {
@@ -4811,7 +4806,7 @@ lock_rec_queue_validate(
if (!page_rec_is_user_rec(rec)) {
- for (lock = lock_rec_get_first(lock_sys.rec_hash,
+ for (lock = lock_rec_get_first(&lock_sys.rec_hash,
block, heap_no);
lock != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) {
@@ -4896,7 +4891,7 @@ func_exit:
mutex_exit(&impl_trx->mutex);
}
- for (lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
lock != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) {
@@ -4965,7 +4960,7 @@ lock_rec_validate_page(
lock_mutex_enter();
loop:
lock = lock_rec_get_first_on_page_addr(
- lock_sys.rec_hash,
+ &lock_sys.rec_hash,
block->page.id().space(), block->page.id().page_no());
if (!lock) {
@@ -5044,7 +5039,7 @@ lock_rec_validate(
ut_ad(lock_mutex_own());
for (const lock_t* lock = static_cast<const lock_t*>(
- HASH_GET_FIRST(lock_sys.rec_hash, start));
+ HASH_GET_FIRST(&lock_sys.rec_hash, start));
lock != NULL;
lock = static_cast<const lock_t*>(HASH_GET_NEXT(hash, lock))) {
@@ -5164,7 +5159,7 @@ lock_validate()
don't want to hog the lock_sys_t::mutex. Release it during the
validation check. */
- for (ulint i = 0; i < hash_get_n_cells(lock_sys.rec_hash); i++) {
+ for (ulint i = 0; i < lock_sys.rec_hash.n_cells; i++) {
ib_uint64_t limit = 0;
while (const lock_t* lock = lock_rec_validate(i, &limit)) {
@@ -5245,7 +5240,7 @@ lock_rec_insert_check_and_lock(
BTR_NO_LOCKING_FLAG and skip the locking altogether. */
ut_ad(lock_table_has(trx, index->table, LOCK_IX));
- lock = lock_rec_get_first(lock_sys.rec_hash, block, heap_no);
+ lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
if (lock == NULL) {
/* We optimize CPU time usage in the simplest case */
@@ -6479,11 +6474,9 @@ DeadlockChecker::get_first_lock(ulint* heap_no) const
const lock_t* lock = m_wait_lock;
if (lock_get_type_low(lock) == LOCK_REC) {
- hash_table_t* lock_hash;
-
- lock_hash = lock->type_mode & LOCK_PREDICATE
- ? lock_sys.prdt_hash
- : lock_sys.rec_hash;
+ hash_table_t* lock_hash = lock->type_mode & LOCK_PREDICATE
+ ? &lock_sys.prdt_hash
+ : &lock_sys.rec_hash;
/* We are only interested in records that match the heap_no. */
*heap_no = lock_rec_find_set_bit(lock);
diff --git a/storage/innobase/lock/lock0prdt.cc b/storage/innobase/lock/lock0prdt.cc
index 512793a1786..a04fd3fe73c 100644
--- a/storage/innobase/lock/lock0prdt.cc
+++ b/storage/innobase/lock/lock0prdt.cc
@@ -541,7 +541,7 @@ lock_prdt_insert_check_and_lock(
lock_t* lock;
/* Only need to check locks on prdt_hash */
- lock = lock_rec_get_first(lock_sys.prdt_hash, block, PRDT_HEAPNO);
+ lock = lock_rec_get_first(&lock_sys.prdt_hash, block, PRDT_HEAPNO);
if (lock == NULL) {
lock_mutex_exit();
@@ -628,7 +628,7 @@ lock_prdt_update_parent(
/* Get all locks in parent */
for (lock = lock_rec_get_first_on_page_addr(
- lock_sys.prdt_hash, space, page_no);
+ &lock_sys.prdt_hash, space, page_no);
lock;
lock = lock_rec_get_next_on_page(lock)) {
lock_prdt_t* lock_prdt;
@@ -815,8 +815,8 @@ lock_prdt_lock(
ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE));
hash_table_t* hash = type_mode == LOCK_PREDICATE
- ? lock_sys.prdt_hash
- : lock_sys.prdt_page_hash;
+ ? &lock_sys.prdt_hash
+ : &lock_sys.prdt_page_hash;
/* Another transaction cannot have an implicit lock on the record,
because when we come here, we already have modified the clustered
@@ -925,7 +925,7 @@ lock_place_prdt_page_lock(
lock_mutex_enter();
const lock_t* lock = lock_rec_get_first_on_page_addr(
- lock_sys.prdt_page_hash, space, page_no);
+ &lock_sys.prdt_page_hash, space, page_no);
const ulint mode = LOCK_S | LOCK_PRDT_PAGE;
trx_t* trx = thr_get_trx(thr);
@@ -981,7 +981,7 @@ lock_test_prdt_page_lock(
lock_mutex_enter();
lock = lock_rec_get_first_on_page_addr(
- lock_sys.prdt_page_hash, space, page_no);
+ &lock_sys.prdt_page_hash, space, page_no);
lock_mutex_exit();
@@ -999,16 +999,10 @@ lock_prdt_rec_move(
const buf_block_t* donator) /*!< in: buffer block containing
the donating record */
{
- lock_t* lock;
-
- if (!lock_sys.prdt_hash) {
- return;
- }
-
lock_mutex_enter();
- for (lock = lock_rec_get_first(lock_sys.prdt_hash,
- donator, PRDT_HEAPNO);
+ for (lock_t *lock = lock_rec_get_first(&lock_sys.prdt_hash,
+ donator, PRDT_HEAPNO);
lock != NULL;
lock = lock_rec_get_next(PRDT_HEAPNO, lock)) {
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index fb797f05f79..66aa6a679cb 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -152,7 +152,7 @@ struct trx_i_s_cache_t {
i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
/** the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
#define LOCKS_HASH_CELLS_NUM 10000
- hash_table_t* locks_hash; /*!< hash table used to eliminate
+ hash_table_t locks_hash; /*!< hash table used to eliminate
duplicate entries in the
innodb_locks table */
/** Initial size of the cache storage */
@@ -923,7 +923,7 @@ search_innodb_locks(
/* hash_chain->"next" */
next,
/* the hash table */
- cache->locks_hash,
+ &cache->locks_hash,
/* fold */
fold_lock(lock, heap_no),
/* the type of the next variable */
@@ -999,7 +999,7 @@ add_lock_to_cache(
/* hash_chain->"next" */
next,
/* the hash table */
- cache->locks_hash,
+ &cache->locks_hash,
/* fold */
fold_lock(lock, heap_no),
/* add this data to the hash */
@@ -1174,7 +1174,7 @@ trx_i_s_cache_clear(
cache->innodb_locks.rows_used = 0;
cache->innodb_lock_waits.rows_used = 0;
- hash_table_clear(cache->locks_hash);
+ cache->locks_hash.clear();
ha_storage_empty(&cache->storage);
}
@@ -1304,7 +1304,7 @@ trx_i_s_cache_init(
table_cache_init(&cache->innodb_lock_waits,
sizeof(i_s_lock_waits_row_t));
- cache->locks_hash = hash_create(LOCKS_HASH_CELLS_NUM);
+ cache->locks_hash.create(LOCKS_HASH_CELLS_NUM);
cache->storage = ha_storage_create(CACHE_STORAGE_INITIAL_SIZE,
CACHE_STORAGE_HASH_CELLS);
@@ -1324,7 +1324,7 @@ trx_i_s_cache_free(
rw_lock_free(&cache->rw_lock);
mutex_free(&cache->last_read_mutex);
- hash_table_free(cache->locks_hash);
+ cache->locks_hash.free();
ha_storage_free(cache->storage);
table_cache_free(&cache->innodb_trx);
table_cache_free(&cache->innodb_locks);