diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-18 12:26:28 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-18 14:16:01 +0300 |
commit | cfd3d70ccbbfcf3fdec034be446317741dfae824 (patch) | |
tree | 205817c9ea9252de9f8988ab76da82dc7d0bd7e2 | |
parent | bf3c862faa8efed4a662725ec27586cd69e9228e (diff) | |
download | mariadb-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.
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(®ex_include_list); xb_regex_list_free(®ex_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); |