Commit cfd3d70c authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent bf3c862f
......@@ -157,16 +157,16 @@ typedef std::list<regex_t> regex_list_t;
static regex_list_t regex_include_list;
static regex_list_t regex_exclude_list;
static hash_table_t* tables_include_hash = NULL;
static hash_table_t* tables_exclude_hash = NULL;
static hash_table_t tables_include_hash;
static hash_table_t tables_exclude_hash;
char *xtrabackup_databases = NULL;
char *xtrabackup_databases_file = NULL;
char *xtrabackup_databases_exclude = NULL;
static hash_table_t* databases_include_hash = NULL;
static hash_table_t* databases_exclude_hash = NULL;
static hash_table_t databases_include_hash;
static hash_table_t databases_exclude_hash;
static hash_table_t* inc_dir_tables_hash;
static hash_table_t inc_dir_tables_hash;
struct xb_filter_entry_struct{
char* name;
......@@ -2256,7 +2256,7 @@ check_if_table_matches_filters(const char *name,
const regex_list_t& regex_list,
hash_table_t* tables_hash)
{
if (regex_list.empty() && !tables_hash) {
if (regex_list.empty() && !tables_hash->array) {
return(FALSE);
}
......@@ -2264,11 +2264,8 @@ check_if_table_matches_filters(const char *name,
return(TRUE);
}
if (tables_hash && find_filter_in_hashtable(name, tables_hash, NULL)) {
return(TRUE);
}
return FALSE;
return tables_hash->array &&
find_filter_in_hashtable(name, tables_hash, NULL);
}
enum skip_database_check_result {
......@@ -2294,8 +2291,8 @@ check_if_skip_database(
/* There are some filters for databases, check them */
xb_filter_entry_t* database = NULL;
if (databases_exclude_hash &&
find_filter_in_hashtable(name, databases_exclude_hash,
if (databases_exclude_hash.array &&
find_filter_in_hashtable(name, &databases_exclude_hash,
&database) &&
!database->has_tables) {
/* Database is found and there are no tables specified,
......@@ -2303,8 +2300,8 @@ check_if_skip_database(
return DATABASE_SKIP;
}
if (databases_include_hash) {
if (!find_filter_in_hashtable(name, databases_include_hash,
if (databases_include_hash.array) {
if (!find_filter_in_hashtable(name, &databases_include_hash,
&database)) {
/* Database isn't found, skip the database */
return DATABASE_SKIP;
......@@ -2328,8 +2325,7 @@ check_if_skip_database_by_path(
const char* path /*!< in: path to the db directory. */
)
{
if (databases_include_hash == NULL &&
databases_exclude_hash == NULL) {
if (!databases_include_hash.array && !databases_exclude_hash.array) {
return(FALSE);
}
......@@ -2373,10 +2369,10 @@ check_if_skip_table(
if (regex_exclude_list.empty() &&
regex_include_list.empty() &&
tables_include_hash == NULL &&
tables_exclude_hash == NULL &&
databases_include_hash == NULL &&
databases_exclude_hash == NULL) {
!tables_include_hash.array &&
!tables_exclude_hash.array &&
!databases_include_hash.array &&
!databases_exclude_hash.array) {
return(FALSE);
}
......@@ -2408,22 +2404,22 @@ check_if_skip_table(
without truncating the #P#... suffix so we can backup individual
partitions with regexps like '^test[.]t#P#p5' */
if (check_if_table_matches_filters(buf, regex_exclude_list,
tables_exclude_hash)) {
&tables_exclude_hash)) {
return(TRUE);
}
if (check_if_table_matches_filters(buf, regex_include_list,
tables_include_hash)) {
&tables_include_hash)) {
return(FALSE);
}
if ((eptr = strstr(buf, "#P#")) != NULL) {
*eptr = 0;
if (check_if_table_matches_filters(buf, regex_exclude_list,
tables_exclude_hash)) {
&tables_exclude_hash)) {
return (TRUE);
}
if (check_if_table_matches_filters(buf, regex_include_list,
tables_include_hash)) {
&tables_include_hash)) {
return(FALSE);
}
}
......@@ -2436,7 +2432,7 @@ check_if_skip_table(
if (skip_database == DATABASE_SKIP_SOME_TABLES ||
!regex_include_list.empty() ||
tables_include_hash) {
tables_include_hash.array) {
/* Include lists are present, but qualified name
failed to match any.*/
......@@ -3461,17 +3457,17 @@ xb_filter_entry_t*
xb_add_filter(
/*========================*/
const char* name, /*!< in: name of table/database */
hash_table_t** hash) /*!< in/out: hash to insert into */
hash_table_t* hash) /*!< in/out: hash to insert into */
{
xb_filter_entry_t* entry;
entry = xb_new_filter_entry(name);
if (UNIV_UNLIKELY(*hash == NULL)) {
*hash = hash_create(1000);
if (UNIV_UNLIKELY(!hash->array)) {
hash->create(1000);
}
HASH_INSERT(xb_filter_entry_t,
name_hash, *hash,
name_hash, hash,
ut_fold_string(entry->name),
entry);
......@@ -3509,8 +3505,8 @@ void
xb_register_filter_entry(
/*=====================*/
const char* name, /*!< in: name */
hash_table_t** databases_hash,
hash_table_t** tables_hash
hash_table_t* databases_hash,
hash_table_t* tables_hash
)
{
const char* p;
......@@ -3527,8 +3523,8 @@ xb_register_filter_entry(
strncpy(dbname, name, p - name);
dbname[p - name] = 0;
if (*databases_hash) {
HASH_SEARCH(name_hash, (*databases_hash),
if (databases_hash) {
HASH_SEARCH(name_hash, databases_hash,
ut_fold_string(dbname),
xb_filter_entry_t*,
db_entry, (void) 0,
......@@ -3727,7 +3723,7 @@ xb_filter_hash_free(hash_table_t* hash)
ulint i;
/* free the hash elements */
for (i = 0; i < hash_get_n_cells(hash); i++) {
for (i = 0; i < hash->n_cells; i++) {
xb_filter_entry_t* table;
table = static_cast<xb_filter_entry_t *>
......@@ -3745,8 +3741,7 @@ xb_filter_hash_free(hash_table_t* hash)
}
}
/* free hash */
hash_table_free(hash);
hash->free();
}
static void xb_regex_list_free(regex_list_t* list)
......@@ -3766,20 +3761,20 @@ xb_filters_free()
xb_regex_list_free(&regex_include_list);
xb_regex_list_free(&regex_exclude_list);
if (tables_include_hash) {
xb_filter_hash_free(tables_include_hash);
if (tables_include_hash.array) {
xb_filter_hash_free(&tables_include_hash);
}
if (tables_exclude_hash) {
xb_filter_hash_free(tables_exclude_hash);
if (tables_exclude_hash.array) {
xb_filter_hash_free(&tables_exclude_hash);
}
if (databases_include_hash) {
xb_filter_hash_free(databases_include_hash);
if (databases_include_hash.array) {
xb_filter_hash_free(&databases_include_hash);
}
if (databases_exclude_hash) {
xb_filter_hash_free(databases_exclude_hash);
if (databases_exclude_hash.array) {
xb_filter_hash_free(&databases_exclude_hash);
}
}
......@@ -4644,7 +4639,7 @@ xb_delta_open_matching_space(
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
......
......@@ -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
......
......@@ -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 @@ btr_compress(
/* 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 @@ btr_compress(
}
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 {
......
......@@ -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 @@ 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) {
......
......@@ -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++);
}
......
......@@ -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 @@ inline buf_page_t *buf_pool_t::watch_set(const page_id_t id,
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))
{
......
......@@ -1239,7 +1239,7 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
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:
......
......@@ -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);
......
......@@ -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);
......
......@@ -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))) {
......
......@@ -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();
}
......
/*****************************************************************************
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 */
......
/*****************************************************************************
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);
}
......@@ -1613,7 +1613,7 @@ class buf_pool_t
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 @@ class buf_pool_t
{
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 @@ class buf_pool_t
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 @@ class buf_pool_t
/* 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 @@ class buf_pool_t
/** 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>
......
......@@ -1432,10 +1432,10 @@ class dict_sys_t
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 @@ class dict_sys_t
/** 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 @@ class dict_sys_t
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 @@ class dict_sys_t
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 @@ class dict_sys_t
+ (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;
}
};
......
......@@ -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);
......
......@@ -1217,9 +1217,8 @@ struct fil_system_t {
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
......
......@@ -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);
}
/*************************************************************//**
......
......@@ -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);
}
......@@ -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"
/*****************************************************************************
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);
}
......@@ -759,12 +759,12 @@ class lock_sys_t
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
......
......@@ -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;
}
}
......
This diff is collapsed.
......@@ -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)) {
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment