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.
This commit is contained in:
Marko Mäkelä 2020-06-18 12:26:28 +03:00
commit cfd3d70ccb
26 changed files with 284 additions and 480 deletions

View file

@ -157,16 +157,16 @@ typedef std::list<regex_t> regex_list_t;
static regex_list_t regex_include_list; static regex_list_t regex_include_list;
static regex_list_t regex_exclude_list; static regex_list_t regex_exclude_list;
static hash_table_t* tables_include_hash = NULL; static hash_table_t tables_include_hash;
static hash_table_t* tables_exclude_hash = NULL; static hash_table_t tables_exclude_hash;
char *xtrabackup_databases = NULL; char *xtrabackup_databases = NULL;
char *xtrabackup_databases_file = NULL; char *xtrabackup_databases_file = NULL;
char *xtrabackup_databases_exclude = NULL; char *xtrabackup_databases_exclude = NULL;
static hash_table_t* databases_include_hash = NULL; static hash_table_t databases_include_hash;
static hash_table_t* databases_exclude_hash = NULL; 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{ struct xb_filter_entry_struct{
char* name; char* name;
@ -2256,7 +2256,7 @@ check_if_table_matches_filters(const char *name,
const regex_list_t& regex_list, const regex_list_t& regex_list,
hash_table_t* tables_hash) hash_table_t* tables_hash)
{ {
if (regex_list.empty() && !tables_hash) { if (regex_list.empty() && !tables_hash->array) {
return(FALSE); return(FALSE);
} }
@ -2264,11 +2264,8 @@ check_if_table_matches_filters(const char *name,
return(TRUE); return(TRUE);
} }
if (tables_hash && find_filter_in_hashtable(name, tables_hash, NULL)) { return tables_hash->array &&
return(TRUE); find_filter_in_hashtable(name, tables_hash, NULL);
}
return FALSE;
} }
enum skip_database_check_result { enum skip_database_check_result {
@ -2294,8 +2291,8 @@ check_if_skip_database(
/* There are some filters for databases, check them */ /* There are some filters for databases, check them */
xb_filter_entry_t* database = NULL; xb_filter_entry_t* database = NULL;
if (databases_exclude_hash && if (databases_exclude_hash.array &&
find_filter_in_hashtable(name, databases_exclude_hash, find_filter_in_hashtable(name, &databases_exclude_hash,
&database) && &database) &&
!database->has_tables) { !database->has_tables) {
/* Database is found and there are no tables specified, /* Database is found and there are no tables specified,
@ -2303,8 +2300,8 @@ check_if_skip_database(
return DATABASE_SKIP; return DATABASE_SKIP;
} }
if (databases_include_hash) { if (databases_include_hash.array) {
if (!find_filter_in_hashtable(name, databases_include_hash, if (!find_filter_in_hashtable(name, &databases_include_hash,
&database)) { &database)) {
/* Database isn't found, skip the database */ /* Database isn't found, skip the database */
return DATABASE_SKIP; return DATABASE_SKIP;
@ -2328,8 +2325,7 @@ check_if_skip_database_by_path(
const char* path /*!< in: path to the db directory. */ const char* path /*!< in: path to the db directory. */
) )
{ {
if (databases_include_hash == NULL && if (!databases_include_hash.array && !databases_exclude_hash.array) {
databases_exclude_hash == NULL) {
return(FALSE); return(FALSE);
} }
@ -2373,10 +2369,10 @@ check_if_skip_table(
if (regex_exclude_list.empty() && if (regex_exclude_list.empty() &&
regex_include_list.empty() && regex_include_list.empty() &&
tables_include_hash == NULL && !tables_include_hash.array &&
tables_exclude_hash == NULL && !tables_exclude_hash.array &&
databases_include_hash == NULL && !databases_include_hash.array &&
databases_exclude_hash == NULL) { !databases_exclude_hash.array) {
return(FALSE); return(FALSE);
} }
@ -2408,22 +2404,22 @@ check_if_skip_table(
without truncating the #P#... suffix so we can backup individual without truncating the #P#... suffix so we can backup individual
partitions with regexps like '^test[.]t#P#p5' */ partitions with regexps like '^test[.]t#P#p5' */
if (check_if_table_matches_filters(buf, regex_exclude_list, if (check_if_table_matches_filters(buf, regex_exclude_list,
tables_exclude_hash)) { &tables_exclude_hash)) {
return(TRUE); return(TRUE);
} }
if (check_if_table_matches_filters(buf, regex_include_list, if (check_if_table_matches_filters(buf, regex_include_list,
tables_include_hash)) { &tables_include_hash)) {
return(FALSE); return(FALSE);
} }
if ((eptr = strstr(buf, "#P#")) != NULL) { if ((eptr = strstr(buf, "#P#")) != NULL) {
*eptr = 0; *eptr = 0;
if (check_if_table_matches_filters(buf, regex_exclude_list, if (check_if_table_matches_filters(buf, regex_exclude_list,
tables_exclude_hash)) { &tables_exclude_hash)) {
return (TRUE); return (TRUE);
} }
if (check_if_table_matches_filters(buf, regex_include_list, if (check_if_table_matches_filters(buf, regex_include_list,
tables_include_hash)) { &tables_include_hash)) {
return(FALSE); return(FALSE);
} }
} }
@ -2436,7 +2432,7 @@ check_if_skip_table(
if (skip_database == DATABASE_SKIP_SOME_TABLES || if (skip_database == DATABASE_SKIP_SOME_TABLES ||
!regex_include_list.empty() || !regex_include_list.empty() ||
tables_include_hash) { tables_include_hash.array) {
/* Include lists are present, but qualified name /* Include lists are present, but qualified name
failed to match any.*/ failed to match any.*/
@ -3461,17 +3457,17 @@ xb_filter_entry_t*
xb_add_filter( xb_add_filter(
/*========================*/ /*========================*/
const char* name, /*!< in: name of table/database */ 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; xb_filter_entry_t* entry;
entry = xb_new_filter_entry(name); entry = xb_new_filter_entry(name);
if (UNIV_UNLIKELY(*hash == NULL)) { if (UNIV_UNLIKELY(!hash->array)) {
*hash = hash_create(1000); hash->create(1000);
} }
HASH_INSERT(xb_filter_entry_t, HASH_INSERT(xb_filter_entry_t,
name_hash, *hash, name_hash, hash,
ut_fold_string(entry->name), ut_fold_string(entry->name),
entry); entry);
@ -3509,8 +3505,8 @@ void
xb_register_filter_entry( xb_register_filter_entry(
/*=====================*/ /*=====================*/
const char* name, /*!< in: name */ const char* name, /*!< in: name */
hash_table_t** databases_hash, hash_table_t* databases_hash,
hash_table_t** tables_hash hash_table_t* tables_hash
) )
{ {
const char* p; const char* p;
@ -3527,8 +3523,8 @@ xb_register_filter_entry(
strncpy(dbname, name, p - name); strncpy(dbname, name, p - name);
dbname[p - name] = 0; dbname[p - name] = 0;
if (*databases_hash) { if (databases_hash) {
HASH_SEARCH(name_hash, (*databases_hash), HASH_SEARCH(name_hash, databases_hash,
ut_fold_string(dbname), ut_fold_string(dbname),
xb_filter_entry_t*, xb_filter_entry_t*,
db_entry, (void) 0, db_entry, (void) 0,
@ -3727,7 +3723,7 @@ xb_filter_hash_free(hash_table_t* hash)
ulint i; ulint i;
/* free the hash elements */ /* 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; xb_filter_entry_t* table;
table = static_cast<xb_filter_entry_t *> table = static_cast<xb_filter_entry_t *>
@ -3745,8 +3741,7 @@ xb_filter_hash_free(hash_table_t* hash)
} }
} }
/* free hash */ hash->free();
hash_table_free(hash);
} }
static void xb_regex_list_free(regex_list_t* list) 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_include_list);
xb_regex_list_free(&regex_exclude_list); xb_regex_list_free(&regex_exclude_list);
if (tables_include_hash) { if (tables_include_hash.array) {
xb_filter_hash_free(tables_include_hash); xb_filter_hash_free(&tables_include_hash);
} }
if (tables_exclude_hash) { if (tables_exclude_hash.array) {
xb_filter_hash_free(tables_exclude_hash); xb_filter_hash_free(&tables_exclude_hash);
} }
if (databases_include_hash) { if (databases_include_hash.array) {
xb_filter_hash_free(databases_include_hash); xb_filter_hash_free(&databases_include_hash);
} }
if (databases_exclude_hash) { if (databases_exclude_hash.array) {
xb_filter_hash_free(databases_exclude_hash); xb_filter_hash_free(&databases_exclude_hash);
} }
} }
@ -4644,7 +4639,7 @@ exit:
table->name = ((char*)table) + sizeof(xb_filter_entry_t); table->name = ((char*)table) + sizeof(xb_filter_entry_t);
strcpy(table->name, dest_space_name); 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); ut_fold_string(table->name), table);
mutex_enter(&fil_system.mutex); mutex_enter(&fil_system.mutex);
@ -5034,7 +5029,7 @@ rm_if_not_found(
/* Truncate ".ibd" */ /* Truncate ".ibd" */
name[strlen(name) - 4] = '\0'; 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*, xb_filter_entry_t*,
table, (void) 0, table, (void) 0,
!strcmp(table->name, name)); !strcmp(table->name, name));
@ -5410,7 +5405,7 @@ static bool xtrabackup_prepare_func(char** argv)
goto error_cleanup; goto error_cleanup;
} }
inc_dir_tables_hash = hash_create(1000); inc_dir_tables_hash.create(1000);
ok = xtrabackup_apply_deltas(); ok = xtrabackup_apply_deltas();
@ -5423,7 +5418,7 @@ static bool xtrabackup_prepare_func(char** argv)
xb_process_datadir("./", ".ibd", rm_if_not_found); 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(); fil_system.close();
#ifdef WITH_INNODB_DISALLOW_WRITES #ifdef WITH_INNODB_DISALLOW_WRITES

View file

@ -57,7 +57,6 @@ SET(INNOBASE_SOURCES
fsp/fsp0sysspace.cc fsp/fsp0sysspace.cc
fut/fut0lst.cc fut/fut0lst.cc
ha/ha0storage.cc ha/ha0storage.cc
ha/hash0hash.cc
fts/fts0fts.cc fts/fts0fts.cc
fts/fts0ast.cc fts/fts0ast.cc
fts/fts0blex.cc fts/fts0blex.cc
@ -163,7 +162,6 @@ SET(INNOBASE_SOURCES
include/ha0storage.ic include/ha0storage.ic
include/handler0alter.h include/handler0alter.h
include/hash0hash.h include/hash0hash.h
include/hash0hash.ic
include/ib0mutex.h include/ib0mutex.h
include/ibuf0ibuf.h include/ibuf0ibuf.h
include/ibuf0ibuf.ic include/ibuf0ibuf.ic

View file

@ -3349,7 +3349,7 @@ btr_lift_page_up(
if (dict_index_is_spatial(index)) { if (dict_index_is_spatial(index)) {
lock_mutex_enter(); lock_mutex_enter();
lock_prdt_page_free_from_discard( lock_prdt_page_free_from_discard(
block, lock_sys.prdt_page_hash); block, &lock_sys.prdt_page_hash);
lock_mutex_exit(); lock_mutex_exit();
} }
lock_update_copy_and_discard(father_block, block); lock_update_copy_and_discard(father_block, block);
@ -3604,7 +3604,7 @@ retry:
/* No GAP lock needs to be worrying about */ /* No GAP lock needs to be worrying about */
lock_mutex_enter(); lock_mutex_enter();
lock_prdt_page_free_from_discard( 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_rec_free_all_from_discard_page(block);
lock_mutex_exit(); lock_mutex_exit();
} else { } else {
@ -3757,7 +3757,7 @@ retry:
} }
lock_mutex_enter(); lock_mutex_enter();
lock_prdt_page_free_from_discard( 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_rec_free_all_from_discard_page(block);
lock_mutex_exit(); lock_mutex_exit();
} else { } else {

View file

@ -492,8 +492,7 @@ static bool ha_insert_for_fold(hash_table_t *table, mem_heap_t* heap,
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
ut_ad(btr_search_enabled); ut_ad(btr_search_enabled);
ulint hash = hash_calc_hash(fold, table); hash_cell_t *cell= &table->array[table->calc_hash(fold)];
hash_cell_t *cell= hash_get_nth_cell(table, hash);
for (ha_node_t *prev= static_cast<ha_node_t*>(cell->node); prev; for (ha_node_t *prev= static_cast<ha_node_t*>(cell->node); prev;
prev= prev->next) 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. */ /* Compact the heap of nodes by moving the top in the place of del_node. */
*del_node= *top; *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 */ /* Look for the pointer to the top node, to update it */
if (cell->node == top) 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]; 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++) { for (i = 0; i < cell_count; i++) {
/* We release search latches every once in a while to /* 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); 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) { 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) { for (; node != NULL; node = node->next) {
const buf_block_t* block const buf_block_t* block
@ -2292,7 +2291,7 @@ state_ok:
mutex_enter(&buf_pool.mutex); 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) { if (cell_count != curr_cell_count) {

View file

@ -359,7 +359,7 @@ buf_buddy_block_free(void* buf)
ut_ad(mutex_own(&buf_pool.mutex)); ut_ad(mutex_own(&buf_pool.mutex));
ut_a(!ut_align_offset(buf, srv_page_size)); 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 ut_ad(bpage->state() == BUF_BLOCK_MEMORY
&& bpage->in_zip_hash), && bpage->in_zip_hash),
((buf_block_t*) bpage)->frame == buf); ((buf_block_t*) bpage)->frame == buf);
@ -367,7 +367,7 @@ buf_buddy_block_free(void* buf)
ut_a(bpage->state() == BUF_BLOCK_MEMORY); ut_a(bpage->state() == BUF_BLOCK_MEMORY);
ut_ad(bpage->in_zip_hash); ut_ad(bpage->in_zip_hash);
ut_d(bpage->in_zip_hash = false); 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)); ut_d(memset(buf, 0, srv_page_size));
UNIV_MEM_INVALID(buf, 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_ad(!block->page.in_zip_hash);
ut_d(block->page.in_zip_hash = true); 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++); ut_d(buf_pool.buddy_n_frames++);
} }

View file

@ -1523,11 +1523,11 @@ bool buf_pool_t::create()
ut_a(srv_n_page_hash_locks != 0); ut_a(srv_n_page_hash_locks != 0);
ut_a(srv_n_page_hash_locks <= MAX_PAGE_HASH_LOCKS); 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--; ) for (auto i= srv_n_page_hash_locks; i--; )
rw_lock_create(hash_table_locks_key, &page_hash_latches[i], rw_lock_create(hash_table_locks_key, &page_hash_latches[i],
SYNC_BUF_PAGE_HASH); SYNC_BUF_PAGE_HASH);
zip_hash= hash_create(2 * curr_size); zip_hash.create(2 * curr_size);
last_printout_time= time(NULL); last_printout_time= time(NULL);
mutex_create(LATCH_ID_FLUSH_LIST, &flush_list_mutex); mutex_create(LATCH_ID_FLUSH_LIST, &flush_list_mutex);
@ -1606,8 +1606,8 @@ void buf_pool_t::close()
chunks= nullptr; chunks= nullptr;
for (auto i= srv_n_page_hash_locks; i--; ) for (auto i= srv_n_page_hash_locks; i--; )
rw_lock_free(&page_hash_latches[i]); rw_lock_free(&page_hash_latches[i]);
hash_table_free(page_hash); page_hash.free();
hash_table_free(zip_hash); zip_hash.free();
io_buf.close(); io_buf.close();
UT_DELETE(chunk_t::map_reg); 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(); const ulint fold = id.fold();
ut_ad(&block->page == page_hash_get_low(id, fold)); ut_ad(&block->page == page_hash_get_low(id, fold));
ut_d(block->page.in_page_hash = false); 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); &block->page, &new_block->page);
buf_block_modify_clock_inc(block); buf_block_modify_clock_inc(block);
@ -1924,44 +1924,46 @@ inline bool buf_pool_t::withdraw_blocks()
/** resize page_hash and zip_hash */ /** resize page_hash and zip_hash */
static void buf_pool_resize_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*> 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; buf_page_t *prev_bpage= bpage;
ut_ad(bpage->in_page_hash); ut_ad(bpage->in_page_hash);
bpage= static_cast<buf_page_t*>(HASH_GET_NEXT(hash, prev_bpage)); bpage= static_cast<buf_page_t*>(HASH_GET_NEXT(hash, prev_bpage));
const ulint fold= prev_bpage->id().fold(); const ulint fold= prev_bpage->id().fold();
HASH_DELETE(buf_page_t, hash, buf_pool.page_hash, fold, prev_bpage); 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_INSERT(buf_page_t, hash, &new_hash, fold, prev_bpage);
} }
} }
std::swap(buf_pool.page_hash->array, new_hash_table->array); std::swap(buf_pool.page_hash.array, new_hash.array);
buf_pool.page_hash->n_cells= new_hash_table->n_cells; buf_pool.page_hash.n_cells= new_hash.n_cells;
hash_table_free(new_hash_table); new_hash.free();
/* recreate zip_hash */ /* 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*> 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; buf_page_t *prev_bpage= bpage;
bpage= static_cast<buf_page_t*>(HASH_GET_NEXT(hash, prev_bpage)); bpage= static_cast<buf_page_t*>(HASH_GET_NEXT(hash, prev_bpage));
const ulint fold= BUF_POOL_ZIP_FOLD_BPAGE(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_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_INSERT(buf_page_t, hash, &new_hash, fold, prev_bpage);
} }
} }
hash_table_free(buf_pool.zip_hash); std::swap(buf_pool.zip_hash.array, new_hash.array);
buf_pool.zip_hash= new_hash_table; 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(bpage->in_page_hash);
ut_ad(dpage->in_page_hash); ut_ad(dpage->in_page_hash);
ut_d(bpage->in_page_hash= false); 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 /** Register a watch for a page identifier. The caller must hold an
@ -2502,7 +2504,7 @@ retry:
w->buf_fix_count_= 1; w->buf_fix_count_= 1;
ut_ad(!w->in_page_hash); ut_ad(!w->in_page_hash);
ut_d(w->in_page_hash= true); /* Not holding buf_pool.mutex here! */ 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; return nullptr;
} }
@ -3772,8 +3774,7 @@ buf_page_create(fil_space_t *space, uint32_t offset,
rw_lock_x_lock(hash_lock); rw_lock_x_lock(hash_lock);
block->page.set_state(BUF_BLOCK_FILE_PAGE); block->page.set_state(BUF_BLOCK_FILE_PAGE);
ut_d(block->page.in_page_hash= true); ut_d(block->page.in_page_hash= true);
HASH_INSERT(buf_page_t, hash, buf_pool.page_hash, page_id.fold(), HASH_INSERT(buf_page_t, hash, &buf_pool.page_hash, fold, &block->page);
&block->page);
if (UNIV_UNLIKELY(zip_size)) if (UNIV_UNLIKELY(zip_size))
{ {

View file

@ -1239,7 +1239,7 @@ func_exit:
ut_ad(b->in_LRU_list); ut_ad(b->in_LRU_list);
ut_ad(b->in_page_hash); 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. */ /* Insert b where bpage was in the LRU list. */
if (prev_b) { 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); 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()) { switch (bpage->state()) {
case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_PAGE:

View file

@ -59,7 +59,7 @@ inline void buf_pool_t::watch_remove(buf_page_t *watch)
{ {
ut_ad(watch->in_page_hash); ut_ad(watch->in_page_hash);
ut_d(watch->in_page_hash= false); 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); watch->set_buf_fix_count(0);
} }
ut_ad(!watch->in_page_hash); 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); block->page.set_state(BUF_BLOCK_FILE_PAGE);
ut_ad(!block->page.in_page_hash); ut_ad(!block->page.in_page_hash);
ut_d(block->page.in_page_hash= true); 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); rw_lock_x_unlock(hash_lock);
/* The block must be put to the LRU list, to the old blocks */ /* 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_ad(!bpage->in_page_hash);
ut_d(bpage->in_page_hash= true); 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); bpage->set_io_fix(BUF_IO_READ);
rw_lock_x_unlock(hash_lock); rw_lock_x_unlock(hash_lock);

View file

@ -1034,9 +1034,9 @@ void dict_sys_t::create()
const ulint hash_size = buf_pool_get_curr_size() const ulint hash_size = buf_pool_get_curr_size()
/ (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE);
table_hash= hash_create(hash_size); table_hash.create(hash_size);
table_id_hash= hash_create(hash_size); table_id_hash.create(hash_size);
temp_id_hash= hash_create(hash_size); temp_id_hash.create(hash_size);
rw_lock_create(dict_operation_lock_key, &latch, SYNC_DICT_OPERATION); 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 */ /* Look for a table with the same name: error if such exists */
{ {
dict_table_t* table2; 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), dict_table_t*, table2, ut_ad(table2->cached),
!strcmp(table2->name.m_name, table->name.m_name)); !strcmp(table2->name.m_name, table->name.m_name));
ut_a(table2 == NULL); ut_a(table2 == NULL);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/* Look for the same table pointer with a different name */ /* 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), dict_table_t*, table2, ut_ad(table2->cached),
table2 == table); table2 == table);
ut_ad(table2 == NULL); ut_ad(table2 == NULL);
#endif /* UNIV_DEBUG */ #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 */ /* Look for a table with the same id: error if such exists */
hash_table_t* id_hash = table->is_temporary() 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); const ulint id_fold = ut_fold_ull(table->id);
{ {
dict_table_t* table2; 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 */ /* Look for a table with the same name: error if such exists */
dict_table_t* table2; 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), dict_table_t*, table2, ut_ad(table2->cached),
(strcmp(table2->name.m_name, new_name) == 0)); (strcmp(table2->name.m_name, new_name) == 0));
DBUG_EXECUTE_IF("dict_table_rename_in_cache_failure", 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 */ /* 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); ut_fold_string(old_name), table);
if (strlen(new_name) > strlen(table->name.m_name)) { 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); strcpy(table->name.m_name, new_name);
/* Add table to hash table of tables */ /* 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); table);
if (!rename_also_foreigns) { if (!rename_also_foreigns) {
@ -1896,12 +1896,12 @@ dict_table_change_id_in_cache(
/* Remove the table from the hash table of id's */ /* 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); ut_fold_ull(table->id), table);
table->id = new_id; table->id = new_id;
/* Add the table back to the hash table */ /* 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); 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 */ /* 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); ut_fold_string(table->name.m_name), table);
hash_table_t* id_hash = table->is_temporary() 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); const ulint id_fold = ut_fold_ull(table->id);
HASH_DELETE(dict_table_t, id_hash, id_hash, id_fold, table); HASH_DELETE(dict_table_t, id_hash, id_hash, id_fold, table);
@ -4880,36 +4880,37 @@ void dict_sys_t::resize()
mutex_enter(&mutex); mutex_enter(&mutex);
/* all table entries are in table_LRU and table_non_LRU lists */ /* all table entries are in table_LRU and table_non_LRU lists */
hash_table_free(table_hash); table_hash.free();
hash_table_free(table_id_hash); table_id_hash.free();
hash_table_free(temp_id_hash); temp_id_hash.free();
const ulint hash_size = buf_pool_get_curr_size() const ulint hash_size = buf_pool_get_curr_size()
/ (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE);
table_hash = hash_create(hash_size); table_hash.create(hash_size);
table_id_hash = hash_create(hash_size); table_id_hash.create(hash_size);
temp_id_hash = 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)) table= UT_LIST_GET_NEXT(table_LRU, table))
{ {
ut_ad(!table->is_temporary()); ut_ad(!table->is_temporary());
ulint fold= ut_fold_string(table->name.m_name); ulint fold= ut_fold_string(table->name.m_name);
ulint id_fold= ut_fold_ull(table->id); 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_INSERT(dict_table_t, id_hash, table_id_hash, id_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; for (dict_table_t *table = UT_LIST_GET_FIRST(table_non_LRU); table;
table = UT_LIST_GET_NEXT(table_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); 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() hash_table_t *id_hash= table->is_temporary()
? temp_id_hash : table_id_hash; ? &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);
} }
@ -4927,27 +4928,19 @@ void dict_sys_t::close()
/* Free the hash elements. We don't remove them from the table /* Free the hash elements. We don't remove them from the table
because we are going to destroy the table anyway. */ because we are going to destroy the table anyway. */
for (ulint i = 0; i < hash_get_n_cells(table_hash); i++) for (ulint i= table_hash.n_cells; i--; )
{ while (dict_table_t *table= static_cast<dict_table_t*>
dict_table_t* table = static_cast<dict_table_t*>(HASH_GET_FIRST(table_hash, (HASH_GET_FIRST(&table_hash, i)))
i)); dict_sys.remove(table);
while (table) table_hash.free();
{
dict_table_t* prev_table = table;
table = static_cast<dict_table_t*>(HASH_GET_NEXT(name_hash, prev_table));
dict_sys.remove(prev_table);
}
}
hash_table_free(table_hash);
/* table_id_hash contains the same elements as in table_hash, /* table_id_hash contains the same elements as in table_hash,
therefore we don't delete the individual elements. */ 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. */ /* No temporary tables should exist at this point. */
hash_table_free(temp_id_hash); temp_id_hash.free();
mutex_exit(&mutex); mutex_exit(&mutex);
mutex_free(&mutex); mutex_free(&mutex);

View file

@ -257,7 +257,7 @@ fil_space_get_by_id(
ut_ad(fil_system.is_initialised()); ut_ad(fil_system.is_initialised());
ut_ad(mutex_own(&fil_system.mutex)); 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, fil_space_t*, space,
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N), ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
space->id == id); space->id == id);
@ -987,7 +987,7 @@ std::vector<pfs_os_file_t> fil_system_t::detach(fil_space_t *space,
bool detach_handle) bool detach_handle)
{ {
ut_ad(mutex_own(&fil_system.mutex)); 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) if (space->is_in_unflushed_spaces)
{ {
@ -1210,7 +1210,7 @@ fil_space_create(
space->atomic_write_supported = true; 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); 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(!is_initialised());
ut_ad(!(srv_page_size % FSP_EXTENT_SIZE)); ut_ad(!(srv_page_size % FSP_EXTENT_SIZE));
ut_ad(srv_page_size); ut_ad(srv_page_size);
ut_ad(!spaces); ut_ad(!spaces.array);
m_initialised = true; m_initialised = true;
@ -1454,7 +1454,7 @@ void fil_system_t::create(ulint hash_size)
mutex_create(LATCH_ID_FIL_SYSTEM, &mutex); mutex_create(LATCH_ID_FIL_SYSTEM, &mutex);
spaces = hash_create(hash_size); spaces.create(hash_size);
fil_space_crypt_init(); fil_space_crypt_init();
#ifdef UNIV_LINUX #ifdef UNIV_LINUX
@ -1530,13 +1530,12 @@ void fil_system_t::close()
if (is_initialised()) { if (is_initialised()) {
m_initialised = false; m_initialised = false;
hash_table_free(spaces); spaces.free();
spaces = NULL;
mutex_free(&mutex); mutex_free(&mutex);
fil_space_crypt_cleanup(); fil_space_crypt_cleanup();
} }
ut_ad(!spaces); ut_ad(!spaces.array);
} }
/** Opens all system tablespace data files. They stay open until the /** 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 */ /* 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*>( for (space = static_cast<fil_space_t*>(
HASH_GET_FIRST(fil_system.spaces, i)); HASH_GET_FIRST(&fil_system.spaces, i));
space != 0; space != 0;
space = static_cast<fil_space_t*>( space = static_cast<fil_space_t*>(
HASH_GET_NEXT(hash, space))) { HASH_GET_NEXT(hash, space))) {

View file

@ -1231,8 +1231,8 @@ rtr_check_discard_page(
mutex_exit(&index->rtr_track->rtr_active_mutex); mutex_exit(&index->rtr_track->rtr_active_mutex);
lock_mutex_enter(); lock_mutex_enter();
lock_prdt_page_free_from_discard(block, lock_sys.prdt_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_prdt_page_free_from_discard(block, &lock_sys.prdt_page_hash);
lock_mutex_exit(); lock_mutex_exit();
} }

View file

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -53,7 +54,7 @@ ha_storage_get(
HASH_SEARCH( HASH_SEARCH(
next, /* node->"next" */ next, /* node->"next" */
storage->hash, /* the hash table */ &storage->hash, /* the hash table */
fold, /* key */ fold, /* key */
ha_storage_node_t*, /* type of node->next */ ha_storage_node_t*, /* type of node->next */
node, /* auxiliary variable */ node, /* auxiliary variable */
@ -127,7 +128,7 @@ ha_storage_put_memlim(
HASH_INSERT( HASH_INSERT(
ha_storage_node_t, /* type used in the hash chain */ ha_storage_node_t, /* type used in the hash chain */
next, /* node->"next" */ next, /* node->"next" */
storage->hash, /* the hash table */ &storage->hash, /* the hash table */
fold, /* key */ fold, /* key */
node); /* add this data to the hash */ node); /* add this data to the hash */

View file

@ -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);
}

View file

@ -1613,7 +1613,7 @@ public:
rw_lock_t *hash_lock_get_low(ulint fold) const rw_lock_t *hash_lock_get_low(ulint fold) const
{ {
return page_hash_latches + 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}); ulint{srv_n_page_hash_locks});
} }
private: private:
@ -1633,13 +1633,13 @@ public:
{ {
for (;;) 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); rw_lock_t *latch= hash_lock_get_low(fold, n_cells);
if (exclusive) if (exclusive)
rw_lock_x_lock(latch); rw_lock_x_lock(latch);
else else
rw_lock_s_lock(latch); 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; return latch;
if (exclusive) if (exclusive)
rw_lock_x_unlock(latch); rw_lock_x_unlock(latch);
@ -1661,7 +1661,7 @@ public:
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S)); RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
buf_page_t *bpage; buf_page_t *bpage;
/* Look for the page in the hash table */ /* 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()); ut_ad(bpage->in_page_hash), id == bpage->id());
return bpage; return bpage;
} }
@ -1785,7 +1785,7 @@ public:
/* The following is based on watch_remove(). */ /* The following is based on watch_remove(). */
ut_ad(watch->in_page_hash); ut_ad(watch->in_page_hash);
ut_d(watch->in_page_hash= false); 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); rw_lock_x_unlock(hash_lock);
// Now that the watch is detached from page_hash, release it to watch[]. // Now that the watch is detached from page_hash, release it to watch[].
mutex_enter(&mutex); mutex_enter(&mutex);
@ -1874,15 +1874,13 @@ public:
/** Hash table of file pages (buf_page_t::in_file() holds), /** Hash table of file pages (buf_page_t::in_file() holds),
indexed by page_id_t. Protected by both mutex and page_hash_latches[]. */ 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 */ /** Latches protecting page_hash */
mutable rw_lock_t page_hash_latches[MAX_PAGE_HASH_LOCKS]; mutable rw_lock_t page_hash_latches[MAX_PAGE_HASH_LOCKS];
hash_table_t* zip_hash; /*!< hash table of buf_block_t blocks /** map of block->frame to buf_block_t blocks that belong
whose frames are allocated to the to buf_buddy_alloc(); protected by buf_pool.mutex */
zip buddy system, hash_table_t zip_hash;
indexed by block->frame;
protected by buf_pool.mutex*/
/** number of pending read operations */ /** number of pending read operations */
Atomic_counter<ulint> n_pend_reads; Atomic_counter<ulint> n_pend_reads;
Atomic_counter<ulint> Atomic_counter<ulint>

View file

@ -1432,10 +1432,10 @@ public:
header and flushed to a file; in header and flushed to a file; in
recovery this must be derived from recovery this must be derived from
the log records */ 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 */ on name */
/** hash table of persistent table IDs */ /** 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_tables; /*!< SYS_TABLES table */
dict_table_t* sys_columns; /*!< SYS_COLUMNS table */ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
dict_table_t* sys_indexes; /*!< SYS_INDEXES table */ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
@ -1454,7 +1454,7 @@ private:
/** the sequence of temporary table IDs */ /** the sequence of temporary table IDs */
std::atomic<table_id_t> temp_table_id; std::atomic<table_id_t> temp_table_id;
/** hash table of temporary table IDs */ /** hash table of temporary table IDs */
hash_table_t* temp_id_hash; hash_table_t temp_id_hash;
public: public:
/** @return a new temporary table ID */ /** @return a new temporary table ID */
table_id_t get_temporary_table_id() { table_id_t get_temporary_table_id() {
@ -1471,7 +1471,7 @@ public:
ut_ad(mutex_own(&mutex)); ut_ad(mutex_own(&mutex));
dict_table_t* table; dict_table_t* table;
ulint fold = ut_fold_ull(id); 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); ut_ad(table->cached), table->id == id);
if (UNIV_LIKELY(table != NULL)) { if (UNIV_LIKELY(table != NULL)) {
DBUG_ASSERT(table->is_temporary()); DBUG_ASSERT(table->is_temporary());
@ -1490,7 +1490,8 @@ public:
ut_ad(mutex_own(&mutex)); ut_ad(mutex_own(&mutex));
dict_table_t* table; dict_table_t* table;
ulint fold = ut_fold_ull(id); 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); ut_ad(table->cached), table->id == id);
DBUG_ASSERT(!table || !table->is_temporary()); DBUG_ASSERT(!table || !table->is_temporary());
return table; return table;
@ -1592,8 +1593,8 @@ public:
+ (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10 + (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10
+ sizeof(dict_field_t) * 5 /* total number of key fields */ + sizeof(dict_field_t) * 5 /* total number of key fields */
+ 200; /* arbitrary, covering names and overhead */ + 200; /* arbitrary, covering names and overhead */
size += (table_hash->n_cells + table_id_hash->n_cells size += (table_hash.n_cells + table_id_hash.n_cells
+ temp_id_hash->n_cells) * sizeof(hash_cell_t); + temp_id_hash.n_cells) * sizeof(hash_cell_t);
return size; return size;
} }
}; };

View file

@ -84,7 +84,7 @@ dict_table_check_if_in_cache_low(
/* Look for the table name in the hash table */ /* Look for the table name in the hash table */
table_fold = ut_fold_string(table_name); 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), dict_table_t*, table, ut_ad(table->cached),
!strcmp(table->name.m_name, table_name)); !strcmp(table->name.m_name, table_name));
DBUG_RETURN(table); DBUG_RETURN(table);

View file

@ -1217,9 +1217,8 @@ public:
ib_mutex_t mutex; /*!< The mutex protecting the cache */ ib_mutex_t mutex; /*!< The mutex protecting the cache */
fil_space_t* sys_space; /*!< The innodb_system tablespace */ fil_space_t* sys_space; /*!< The innodb_system tablespace */
fil_space_t* temp_space; /*!< The innodb_temporary tablespace */ fil_space_t* temp_space; /*!< The innodb_temporary tablespace */
hash_table_t* spaces; /*!< The hash table of spaces in the /** Map of fil_space_t::id to fil_space_t* */
system; they are hashed on the space hash_table_t spaces;
id */
UT_LIST_BASE_NODE_T(fil_node_t) LRU; UT_LIST_BASE_NODE_T(fil_node_t) LRU;
/*!< base node for the LRU list of the /*!< base node for the LRU list of the
most recently used open files with no most recently used open files with no

View file

@ -93,8 +93,7 @@ ha_chain_get_first(
hash_table_t* table, /*!< in: hash table */ hash_table_t* table, /*!< in: hash table */
ulint fold) /*!< in: fold value determining the chain */ ulint fold) /*!< in: fold value determining the chain */
{ {
return((ha_node_t*) return static_cast<ha_node_t*>(table->array[table->calc_hash(fold)].node);
hash_get_nth_cell(table, hash_calc_hash(fold, table))->node);
} }
/*************************************************************//** /*************************************************************//**

View file

@ -32,7 +32,7 @@ Created September 24, 2007 Vasil Dimov
struct ha_storage_t { struct ha_storage_t {
mem_heap_t* heap; /*!< memory heap from which memory is mem_heap_t* heap; /*!< memory heap from which memory is
allocated */ allocated */
hash_table_t* hash; /*!< hash table used to avoid hash_table_t hash; /*!< hash table used to avoid
duplicates */ duplicates */
}; };
@ -77,7 +77,7 @@ ha_storage_create(
sizeof(ha_storage_t)); sizeof(ha_storage_t));
storage->heap = heap; storage->heap = heap;
storage->hash = hash_create(initial_hash_cells); storage->hash.create(initial_hash_cells);
return(storage); return(storage);
} }
@ -97,7 +97,7 @@ ha_storage_empty(
temp_storage.heap = (*storage)->heap; temp_storage.heap = (*storage)->heap;
temp_storage.hash = (*storage)->hash; temp_storage.hash = (*storage)->hash;
hash_table_clear(temp_storage.hash); temp_storage.hash.clear();
mem_heap_empty(temp_storage.heap); mem_heap_empty(temp_storage.heap);
*storage = (ha_storage_t*) mem_heap_alloc(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 */ ha_storage_t* storage) /*!< in, own: hash storage */
{ {
/* order is important because the pointer storage->hash is storage->hash.free();
within the heap */
hash_table_free(storage->hash);
mem_heap_free(storage->heap); mem_heap_free(storage->heap);
} }
@ -138,7 +136,7 @@ ha_storage_get_size(
/* this assumes hash->heap and hash->heaps are NULL */ /* this assumes hash->heap and hash->heaps are NULL */
ret += sizeof(hash_table_t); 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); return(ret);
} }

View file

@ -33,22 +33,6 @@ struct hash_cell_t{
}; };
typedef void* hash_node_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) #define hash_calc_hash(FOLD, TABLE) (TABLE)->calc_hash(FOLD)
/*******************************************************************//** /*******************************************************************//**
@ -61,7 +45,7 @@ do {\
\ \
(DATA)->NAME = NULL;\ (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) {\ if (cell3333->node == NULL) {\
cell3333->node = DATA;\ cell3333->node = DATA;\
@ -87,7 +71,7 @@ do { \
\ \
(DATA)->NAME = NULL; \ (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) { \ if (cell3333->node == NULL) { \
cell3333->node = DATA; \ cell3333->node = DATA; \
@ -116,7 +100,7 @@ do {\
hash_cell_t* cell3333;\ hash_cell_t* cell3333;\
TYPE* struct3333;\ TYPE* struct3333;\
\ \
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\ cell3333 = &(TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
\ \
if (cell3333->node == DATA) {\ if (cell3333->node == DATA) {\
HASH_ASSERT_VALID(DATA->NAME);\ HASH_ASSERT_VALID(DATA->NAME);\
@ -140,7 +124,7 @@ do {\
(DATA_NEW)->NAME = (DATA_OLD)->NAME; \ (DATA_NEW)->NAME = (DATA_OLD)->NAME; \
\ \
hash_cell_t& cell3333 \ hash_cell_t& cell3333 \
= TABLE->array[hash_calc_hash(FOLD, TABLE)]; \ = (TABLE)->array[(TABLE)->calc_hash(FOLD)]; \
TYPE** struct3333 = (TYPE**)&cell3333.node; \ TYPE** struct3333 = (TYPE**)&cell3333.node; \
while (*struct3333 != DATA_OLD) { \ while (*struct3333 != DATA_OLD) { \
struct3333 = &((*struct3333)->NAME); \ struct3333 = &((*struct3333)->NAME); \
@ -150,8 +134,7 @@ do {\
/*******************************************************************//** /*******************************************************************//**
Gets the first struct in a hash chain, NULL if none. */ Gets the first struct in a hash chain, NULL if none. */
#define HASH_GET_FIRST(TABLE, HASH_VAL)\ #define HASH_GET_FIRST(TABLE, HASH_VAL) (TABLE)->array[HASH_VAL].node
(hash_get_nth_cell(TABLE, HASH_VAL)->node)
/*******************************************************************//** /*******************************************************************//**
Gets the next struct in a hash chain, NULL if none. */ Gets the next struct in a hash chain, NULL if none. */
@ -202,33 +185,6 @@ do { \
} \ } \
} while (0) } 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. */ Move all hash table entries from OLD_TABLE to NEW_TABLE. */
@ -237,7 +193,7 @@ do {\
ulint i2222;\ ulint i2222;\
ulint cell_count2222;\ ulint cell_count2222;\
\ \
cell_count2222 = hash_get_n_cells(OLD_TABLE);\ cell_count2222 = (OLD_TABLE)->n_cells; \
\ \
for (i2222 = 0; i2222 < cell_count2222; i2222++) {\ for (i2222 = 0; i2222 < cell_count2222; i2222++) {\
NODE_TYPE* node2222 = static_cast<NODE_TYPE*>(\ NODE_TYPE* node2222 = static_cast<NODE_TYPE*>(\
@ -256,7 +212,7 @@ do {\
}\ }\
} while (0) } while (0)
/** Hash table with singly-linkde overflow lists */ /** Hash table with singly-linked overflow lists */
struct hash_table_t struct hash_table_t
{ {
/** number of elements in array (a prime number) */ /** number of elements in array (a prime number) */
@ -266,9 +222,17 @@ struct hash_table_t
/** Create the hash table. /** Create the hash table.
@param n the lower bound of n_cells */ @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); } ulint calc_hash(ulint fold) const { return ut_hash_ulint(fold, n_cells); }
}; };
#include "hash0hash.ic"

View file

@ -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);
}

View file

@ -759,12 +759,12 @@ public:
MY_ALIGNED(CACHE_LINE_SIZE) MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex mutex; /*!< Mutex protecting the LockMutex mutex; /*!< Mutex protecting the
locks */ locks */
hash_table_t* rec_hash; /*!< hash table of the record /** record locks */
locks */ hash_table_t rec_hash;
hash_table_t* prdt_hash; /*!< hash table of the predicate /** predicate locks for SPATIAL INDEX */
lock */ hash_table_t prdt_hash;
hash_table_t* prdt_page_hash; /*!< hash table of the page /** page locks for SPATIAL INDEX */
lock */ hash_table_t prdt_page_hash;
MY_ALIGNED(CACHE_LINE_SIZE) MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex wait_mutex; /*!< Mutex protecting the LockMutex wait_mutex; /*!< Mutex protecting the

View file

@ -53,8 +53,7 @@ lock_rec_hash(
ulint space, /*!< in: space */ ulint space, /*!< in: space */
ulint page_no)/*!< in: page number */ ulint page_no)/*!< in: page number */
{ {
return(unsigned(hash_calc_hash(lock_rec_fold(space, page_no), return unsigned(lock_sys.rec_hash.calc_hash(lock_rec_fold(space, page_no)));
lock_sys.rec_hash)));
} }
/*********************************************************************//** /*********************************************************************//**
@ -90,11 +89,11 @@ lock_hash_get(
ulint mode) /*!< in: lock mode */ ulint mode) /*!< in: lock mode */
{ {
if (mode & LOCK_PREDICATE) { if (mode & LOCK_PREDICATE) {
return(lock_sys.prdt_hash); return &lock_sys.prdt_hash;
} else if (mode & LOCK_PRDT_PAGE) { } else if (mode & LOCK_PRDT_PAGE) {
return(lock_sys.prdt_page_hash); return &lock_sys.prdt_page_hash;
} else { } else {
return(lock_sys.rec_hash); return &lock_sys.rec_hash;
} }
} }

View file

@ -463,9 +463,9 @@ void lock_sys_t::create(ulint n_cells)
mutex_create(LATCH_ID_LOCK_SYS_WAIT, &wait_mutex); mutex_create(LATCH_ID_LOCK_SYS_WAIT, &wait_mutex);
rec_hash = hash_create(n_cells); rec_hash.create(n_cells);
prdt_hash = hash_create(n_cells); prdt_hash.create(n_cells);
prdt_page_hash = hash_create(n_cells); prdt_page_hash.create(n_cells);
if (!srv_read_only_mode) { if (!srv_read_only_mode) {
lock_latest_err_file = os_file_create_tmpfile(); lock_latest_err_file = os_file_create_tmpfile();
@ -498,23 +498,23 @@ void lock_sys_t::resize(ulint n_cells)
mutex_enter(&mutex); mutex_enter(&mutex);
hash_table_t* old_hash = rec_hash; hash_table_t old_hash(rec_hash);
rec_hash = hash_create(n_cells); rec_hash.create(n_cells);
HASH_MIGRATE(old_hash, rec_hash, lock_t, hash, HASH_MIGRATE(&old_hash, &rec_hash, lock_t, hash,
lock_rec_lock_fold); lock_rec_lock_fold);
hash_table_free(old_hash); old_hash.free();
old_hash = prdt_hash; old_hash = prdt_hash;
prdt_hash = hash_create(n_cells); prdt_hash.create(n_cells);
HASH_MIGRATE(old_hash, prdt_hash, lock_t, hash, HASH_MIGRATE(&old_hash, &prdt_hash, lock_t, hash,
lock_rec_lock_fold); lock_rec_lock_fold);
hash_table_free(old_hash); old_hash.free();
old_hash = prdt_page_hash; old_hash = prdt_page_hash;
prdt_page_hash = hash_create(n_cells); prdt_page_hash.create(n_cells);
HASH_MIGRATE(old_hash, prdt_page_hash, lock_t, hash, HASH_MIGRATE(&old_hash, &prdt_page_hash, lock_t, hash,
lock_rec_lock_fold); lock_rec_lock_fold);
hash_table_free(old_hash); old_hash.free();
/* need to update block->lock_hash_val */ /* need to update block->lock_hash_val */
mutex_enter(&buf_pool.mutex); mutex_enter(&buf_pool.mutex);
@ -543,9 +543,9 @@ void lock_sys_t::close()
lock_latest_err_file = NULL; lock_latest_err_file = NULL;
} }
hash_table_free(rec_hash); rec_hash.free();
hash_table_free(prdt_hash); prdt_hash.free();
hash_table_free(prdt_page_hash); prdt_page_hash.free();
mutex_destroy(&mutex); mutex_destroy(&mutex);
mutex_destroy(&wait_mutex); mutex_destroy(&wait_mutex);
@ -871,7 +871,7 @@ lock_rec_expl_exist_on_page(
lock_mutex_enter(); lock_mutex_enter();
/* Only used in ibuf pages, so rec_hash is good enough */ /* 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); space, page_no);
lock_mutex_exit(); lock_mutex_exit();
@ -989,7 +989,7 @@ lock_rec_has_expl(
|| (precise_mode & LOCK_MODE_MASK) == LOCK_X); || (precise_mode & LOCK_MODE_MASK) == LOCK_X);
ut_ad(!(precise_mode & LOCK_INSERT_INTENTION)); 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 != NULL;
lock = lock_rec_get_next(heap_no, lock)) { lock = lock_rec_get_next(heap_no, lock)) {
@ -1042,7 +1042,7 @@ lock_rec_other_has_expl_req(
return(NULL); return(NULL);
} }
for (lock_t* lock = lock_rec_get_first(lock_sys.rec_hash, for (lock_t* lock = lock_rec_get_first(&lock_sys.rec_hash,
block, heap_no); block, heap_no);
lock != NULL; lock != NULL;
lock = lock_rec_get_next(heap_no, lock)) { 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); 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 != NULL;
lock = lock_rec_get_next(heap_no, lock)) { lock = lock_rec_get_next(heap_no, lock)) {
@ -1468,7 +1468,7 @@ lock_rec_create_low(
&& innodb_lock_schedule_algorithm && innodb_lock_schedule_algorithm
== INNODB_LOCK_SCHEDULE_ALGORITHM_VATS == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&& !thd_is_replication_slave_thread(trx->mysql_thd)) { && !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); lock_rec_fold(space, page_no), lock);
} else { } else {
HASH_INSERT(lock_t, hash, lock_hash_get(type_mode), 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; page_no = in_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no); rec_fold = lock_rec_fold(space, page_no);
hash = lock_hash_get(in_lock->type_mode); hash = lock_hash_get(in_lock->type_mode);
cell = hash_get_nth_cell(hash, cell = &hash->array[hash->calc_hash(rec_fold)];
hash_calc_hash(rec_fold, hash));
node = (lock_t *) cell->node; node = (lock_t *) cell->node;
// If in_lock is not a wait lock, we insert it to the head of the list. // 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; page_no = in_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no); rec_fold = lock_rec_fold(space, page_no);
hash = lock_hash_get(in_lock->type_mode); hash = lock_hash_get(in_lock->type_mode);
cell = hash_get_nth_cell(hash, cell = &hash->array[hash->calc_hash(rec_fold)];
hash_calc_hash(rec_fold, hash));
next = (lock_t *) cell->node; next = (lock_t *) cell->node;
while (next != NULL) { while (next != NULL) {
// If this is a granted lock, check that there's no wait lock before it. // 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); hash = lock_hash_get(in_lock->type_mode);
cell = hash_get_nth_cell(hash, cell = &hash->array[hash->calc_hash(rec_fold)];
hash_calc_hash(rec_fold, hash));
node = (lock_t *) cell->node; node = (lock_t *) cell->node;
if (node != in_lock) { if (node != in_lock) {
cell->node = in_lock; cell->node = in_lock;
@ -1745,7 +1742,7 @@ lock_rec_enqueue_waiting(
== INNODB_LOCK_SCHEDULE_ALGORITHM_VATS == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&& !prdt && !prdt
&& !thd_is_replication_slave_thread(lock->trx->mysql_thd)) { && !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); lock_rec_lock_fold(lock), lock);
dberr_t res = lock_rec_insert_by_trx_age(lock); dberr_t res = lock_rec_insert_by_trx_age(lock);
if (res != DB_SUCCESS) { if (res != DB_SUCCESS) {
@ -1928,7 +1925,7 @@ lock_rec_lock(
if (lock_table_has(trx, index->table, if (lock_table_has(trx, index->table,
static_cast<lock_mode>(LOCK_MODE_MASK & mode))); 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); trx_mutex_enter(trx);
if (lock_rec_get_next_on_page(lock) || 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* lock;
lock_t* previous = static_cast<lock_t*>( lock_t* previous = static_cast<lock_t*>(
hash_get_nth_cell(lock_sys.rec_hash, lock_sys.rec_hash.array[lock_sys.rec_hash.calc_hash(rec_fold)].
hash_calc_hash(rec_fold, lock_sys.rec_hash)) node);
->node);
if (previous == NULL) { if (previous == NULL) {
return; return;
} }
@ -2229,7 +2225,7 @@ static void lock_rec_dequeue_from_page(lock_t* in_lock)
if (innodb_lock_schedule_algorithm if (innodb_lock_schedule_algorithm
== INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS == 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)) { || thd_is_replication_slave_thread(in_lock->trx->mysql_thd)) {
/* Check if waiting locks in the queue can now be granted: /* Check if waiting locks in the queue can now be granted:
grant locks if there are no conflicting locks ahead. Stop at 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(); page_no = block->page.id().page_no();
lock_rec_free_all_from_discard_page_low( 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( 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( 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 ===================*/ /*============= RECORD LOCK MOVING AND INHERITING ===================*/
@ -2380,12 +2376,12 @@ lock_rec_reset_and_release_wait(
ulint heap_no)/*!< in: heap number of record */ ulint heap_no)/*!< in: heap number of record */
{ {
lock_rec_reset_and_release_wait_low( 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_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_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 DO want S-locks/X-locks(taken for replace) set by a consistency
constraint to be inherited also then. */ 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 != NULL;
lock = lock_rec_get_next(heap_no, lock)) { lock = lock_rec_get_next(heap_no, lock)) {
@ -2454,7 +2450,7 @@ lock_rec_inherit_to_gap_if_gap_lock(
lock_mutex_enter(); 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 != NULL;
lock = lock_rec_get_next(heap_no, lock)) { 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 */ /* If the lock is predicate lock, it resides on INFIMUM record */
ut_ad(lock_rec_get_first( ut_ad(lock_rec_get_first(
lock_hash, receiver, receiver_heap_no) == NULL lock_hash, receiver, receiver_heap_no) == NULL
|| lock_hash == lock_sys.prdt_hash || lock_hash == &lock_sys.prdt_hash
|| lock_hash == lock_sys.prdt_page_hash); || lock_hash == &lock_sys.prdt_page_hash);
for (lock = lock_rec_get_first(lock_hash, for (lock = lock_rec_get_first(lock_hash,
donator, donator_heap_no); donator, donator_heap_no);
@ -2522,8 +2518,8 @@ lock_rec_move_low(
lock->index, lock->trx, FALSE); lock->index, lock->trx, FALSE);
} }
ut_ad(lock_rec_get_first(lock_sys.rec_hash, ut_ad(!lock_rec_get_first(&lock_sys.rec_hash,
donator, donator_heap_no) == NULL); donator, donator_heap_no));
} }
/** Move all the granted locks to the front of the given lock list. /** 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 ulint donator_heap_no)/*!< in: heap_no of the record
which gives the locks */ 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); receiver_heap_no, donator_heap_no);
} }
@ -2602,7 +2598,7 @@ lock_move_reorganize_page(
lock_mutex_enter(); lock_mutex_enter();
/* FIXME: This needs to deal with predicate lock too */ /* 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) { if (lock == NULL) {
lock_mutex_exit(); 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 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. */ 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)) { lock = lock_rec_get_next_on_page(lock)) {
const rec_t* rec1 = rec; const rec_t* rec1 = rec;
const rec_t* rec2; const rec_t* rec2;
@ -2850,7 +2847,8 @@ lock_move_rec_list_start(
lock_mutex_enter(); 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)) { lock = lock_rec_get_next_on_page(lock)) {
const rec_t* rec1; const rec_t* rec1;
const rec_t* rec2; const rec_t* rec2;
@ -2962,7 +2960,8 @@ lock_rtr_move_rec_list(
lock_mutex_enter(); 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)) { lock = lock_rec_get_next_on_page(lock)) {
ulint moved = 0; ulint moved = 0;
const rec_t* rec1; const rec_t* rec1;
@ -3074,12 +3073,12 @@ lock_update_merge_right(
waiting transactions */ waiting transactions */
lock_rec_reset_and_release_wait_low( 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, /* there should exist no page lock on the left page,
otherwise, it will be blocked from merge */ otherwise, it will be blocked from merge */
ut_ad(!lock_rec_get_first_on_page_addr( 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().space(),
left_block->page.id().page_no())); left_block->page.id().page_no()));
@ -3189,7 +3188,7 @@ lock_update_merge_left(
releasing waiting transactions */ releasing waiting transactions */
lock_rec_reset_and_release_wait_low( 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 /* 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, /* there should exist no page lock on the right page,
otherwise, it will be blocked from merge */ otherwise, it will be blocked from merge */
ut_ad(!lock_rec_get_first_on_page_addr( 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().space(),
right_block->page.id().page_no())); right_block->page.id().page_no()));
@ -3254,9 +3253,9 @@ lock_update_discard(
lock_mutex_enter(); lock_mutex_enter();
if (lock_rec_get_first_on_page(lock_sys.rec_hash, block)) { 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_hash, block));
ut_ad(!lock_rec_get_first_on_page(lock_sys.prdt_page_hash, ut_ad(!lock_rec_get_first_on_page(&lock_sys.prdt_page_hash,
block)); block));
/* Inherit all the locks on the page to the record and /* Inherit all the locks on the page to the record and
reset all the locks on the page */ reset all the locks on the page */
@ -3293,14 +3292,14 @@ lock_update_discard(
lock_rec_free_all_from_discard_page_low( lock_rec_free_all_from_discard_page_low(
block->page.id().space(), block->page.id().page_no(), block->page.id().space(), block->page.id().page_no(),
lock_sys.rec_hash); &lock_sys.rec_hash);
} else { } else {
lock_rec_free_all_from_discard_page_low( lock_rec_free_all_from_discard_page_low(
block->page.id().space(), block->page.id().page_no(), 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( lock_rec_free_all_from_discard_page_low(
block->page.id().space(), block->page.id().page_no(), block->page.id().space(), block->page.id().page_no(),
lock_sys.prdt_page_hash); &lock_sys.prdt_page_hash);
} }
lock_mutex_exit(); lock_mutex_exit();
@ -4068,12 +4067,10 @@ run_again:
static static
void void
lock_grant_and_move_on_rec( lock_grant_and_move_on_rec(
hash_table_t* lock_hash,
lock_t* first_lock, lock_t* first_lock,
ulint heap_no) ulint heap_no)
{ {
lock_t* lock; lock_t* lock;
lock_t* previous;
ulint space; ulint space;
ulint page_no; ulint page_no;
ulint rec_fold; ulint rec_fold;
@ -4082,8 +4079,9 @@ lock_grant_and_move_on_rec(
page_no = first_lock->un_member.rec_lock.page_no; page_no = first_lock->un_member.rec_lock.page_no;
rec_fold = lock_rec_fold(space, page_no); rec_fold = lock_rec_fold(space, page_no);
previous = (lock_t *) hash_get_nth_cell(lock_hash, lock_t* previous = static_cast<lock_t*>(
hash_calc_hash(rec_fold, lock_hash))->node; lock_sys.rec_hash.array[lock_sys.rec_hash.calc_hash(rec_fold)]
.node);
if (previous == NULL) { if (previous == NULL) {
return; return;
} }
@ -4155,7 +4153,7 @@ lock_rec_unlock(
lock_mutex_enter(); lock_mutex_enter();
trx_mutex_enter(trx); 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 /* Find the last lock with the same lock_mode and transaction
on the record. */ on the record. */
@ -4204,7 +4202,7 @@ released:
} }
} }
} else { } 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(); 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. Calculates the number of record lock structs in the record lock hash table.
@return number of record locks */ @return number of record locks */
static static ulint lock_get_n_rec_locks()
ulint
lock_get_n_rec_locks(void)
/*======================*/
{ {
ulint n_locks = 0; ulint n_locks = 0;
ulint i; ulint i;
ut_ad(lock_mutex_own()); 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; const lock_t* lock;
for (lock = static_cast<const lock_t*>( 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 != 0;
lock = static_cast<const lock_t*>( lock = static_cast<const lock_t*>(
HASH_GET_NEXT(hash, lock))) { HASH_GET_NEXT(hash, lock))) {
@ -4811,7 +4806,7 @@ lock_rec_queue_validate(
if (!page_rec_is_user_rec(rec)) { 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); block, heap_no);
lock != NULL; lock != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) { lock = lock_rec_get_next_const(heap_no, lock)) {
@ -4896,7 +4891,7 @@ func_exit:
mutex_exit(&impl_trx->mutex); 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 != NULL;
lock = lock_rec_get_next_const(heap_no, lock)) { lock = lock_rec_get_next_const(heap_no, lock)) {
@ -4965,7 +4960,7 @@ lock_rec_validate_page(
lock_mutex_enter(); lock_mutex_enter();
loop: loop:
lock = lock_rec_get_first_on_page_addr( 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()); block->page.id().space(), block->page.id().page_no());
if (!lock) { if (!lock) {
@ -5044,7 +5039,7 @@ lock_rec_validate(
ut_ad(lock_mutex_own()); ut_ad(lock_mutex_own());
for (const lock_t* lock = static_cast<const lock_t*>( 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 != NULL;
lock = static_cast<const lock_t*>(HASH_GET_NEXT(hash, lock))) { 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 don't want to hog the lock_sys_t::mutex. Release it during the
validation check. */ 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; ib_uint64_t limit = 0;
while (const lock_t* lock = lock_rec_validate(i, &limit)) { 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. */ BTR_NO_LOCKING_FLAG and skip the locking altogether. */
ut_ad(lock_table_has(trx, index->table, LOCK_IX)); 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) { if (lock == NULL) {
/* We optimize CPU time usage in the simplest case */ /* 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; const lock_t* lock = m_wait_lock;
if (lock_get_type_low(lock) == LOCK_REC) { if (lock_get_type_low(lock) == LOCK_REC) {
hash_table_t* lock_hash; hash_table_t* lock_hash = lock->type_mode & LOCK_PREDICATE
? &lock_sys.prdt_hash
lock_hash = lock->type_mode & LOCK_PREDICATE : &lock_sys.rec_hash;
? lock_sys.prdt_hash
: lock_sys.rec_hash;
/* We are only interested in records that match the heap_no. */ /* We are only interested in records that match the heap_no. */
*heap_no = lock_rec_find_set_bit(lock); *heap_no = lock_rec_find_set_bit(lock);

View file

@ -541,7 +541,7 @@ lock_prdt_insert_check_and_lock(
lock_t* lock; lock_t* lock;
/* Only need to check locks on prdt_hash */ /* 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) { if (lock == NULL) {
lock_mutex_exit(); lock_mutex_exit();
@ -628,7 +628,7 @@ lock_prdt_update_parent(
/* Get all locks in parent */ /* Get all locks in parent */
for (lock = lock_rec_get_first_on_page_addr( 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 = lock_rec_get_next_on_page(lock)) { lock = lock_rec_get_next_on_page(lock)) {
lock_prdt_t* lock_prdt; lock_prdt_t* lock_prdt;
@ -815,8 +815,8 @@ lock_prdt_lock(
ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE)); ut_ad(type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE));
hash_table_t* hash = type_mode == LOCK_PREDICATE hash_table_t* hash = type_mode == LOCK_PREDICATE
? lock_sys.prdt_hash ? &lock_sys.prdt_hash
: lock_sys.prdt_page_hash; : &lock_sys.prdt_page_hash;
/* Another transaction cannot have an implicit lock on the record, /* Another transaction cannot have an implicit lock on the record,
because when we come here, we already have modified the clustered because when we come here, we already have modified the clustered
@ -925,7 +925,7 @@ lock_place_prdt_page_lock(
lock_mutex_enter(); lock_mutex_enter();
const lock_t* lock = lock_rec_get_first_on_page_addr( 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; const ulint mode = LOCK_S | LOCK_PRDT_PAGE;
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
@ -981,7 +981,7 @@ lock_test_prdt_page_lock(
lock_mutex_enter(); lock_mutex_enter();
lock = lock_rec_get_first_on_page_addr( 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(); lock_mutex_exit();
@ -999,15 +999,9 @@ lock_prdt_rec_move(
const buf_block_t* donator) /*!< in: buffer block containing const buf_block_t* donator) /*!< in: buffer block containing
the donating record */ the donating record */
{ {
lock_t* lock;
if (!lock_sys.prdt_hash) {
return;
}
lock_mutex_enter(); lock_mutex_enter();
for (lock = lock_rec_get_first(lock_sys.prdt_hash, for (lock_t *lock = lock_rec_get_first(&lock_sys.prdt_hash,
donator, PRDT_HEAPNO); donator, PRDT_HEAPNO);
lock != NULL; lock != NULL;
lock = lock_rec_get_next(PRDT_HEAPNO, lock)) { lock = lock_rec_get_next(PRDT_HEAPNO, lock)) {

View file

@ -152,7 +152,7 @@ struct trx_i_s_cache_t {
i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */ i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
/** the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */ /** the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
#define LOCKS_HASH_CELLS_NUM 10000 #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 duplicate entries in the
innodb_locks table */ innodb_locks table */
/** Initial size of the cache storage */ /** Initial size of the cache storage */
@ -923,7 +923,7 @@ search_innodb_locks(
/* hash_chain->"next" */ /* hash_chain->"next" */
next, next,
/* the hash table */ /* the hash table */
cache->locks_hash, &cache->locks_hash,
/* fold */ /* fold */
fold_lock(lock, heap_no), fold_lock(lock, heap_no),
/* the type of the next variable */ /* the type of the next variable */
@ -999,7 +999,7 @@ add_lock_to_cache(
/* hash_chain->"next" */ /* hash_chain->"next" */
next, next,
/* the hash table */ /* the hash table */
cache->locks_hash, &cache->locks_hash,
/* fold */ /* fold */
fold_lock(lock, heap_no), fold_lock(lock, heap_no),
/* add this data to the hash */ /* add this data to the hash */
@ -1174,7 +1174,7 @@ trx_i_s_cache_clear(
cache->innodb_locks.rows_used = 0; cache->innodb_locks.rows_used = 0;
cache->innodb_lock_waits.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); ha_storage_empty(&cache->storage);
} }
@ -1304,7 +1304,7 @@ trx_i_s_cache_init(
table_cache_init(&cache->innodb_lock_waits, table_cache_init(&cache->innodb_lock_waits,
sizeof(i_s_lock_waits_row_t)); 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 = ha_storage_create(CACHE_STORAGE_INITIAL_SIZE,
CACHE_STORAGE_HASH_CELLS); CACHE_STORAGE_HASH_CELLS);
@ -1324,7 +1324,7 @@ trx_i_s_cache_free(
rw_lock_free(&cache->rw_lock); rw_lock_free(&cache->rw_lock);
mutex_free(&cache->last_read_mutex); mutex_free(&cache->last_read_mutex);
hash_table_free(cache->locks_hash); cache->locks_hash.free();
ha_storage_free(cache->storage); ha_storage_free(cache->storage);
table_cache_free(&cache->innodb_trx); table_cache_free(&cache->innodb_trx);
table_cache_free(&cache->innodb_locks); table_cache_free(&cache->innodb_locks);