Skip to content

Commit

Permalink
MDEV-22693 - InnoDB: get rid of casts for rw_trx_hash iterator
Browse files Browse the repository at this point in the history
Less error prone, stricter type control.
  • Loading branch information
svoj committed May 30, 2020
1 parent 043828b commit ccdfced
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 45 deletions.
61 changes: 35 additions & 26 deletions storage/innobase/include/trx0sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ class rw_trx_hash_t
LF_HASH hash;


template <typename T>
using walk_action= my_bool(rw_trx_hash_element_t *element, T *action);


/**
Constructor callback for lock-free allocator.
Expand Down Expand Up @@ -487,18 +491,19 @@ class rw_trx_hash_t
}


struct eliminate_duplicates_arg
template <typename T> struct eliminate_duplicates_arg
{
trx_ids_t ids;
my_hash_walk_action action;
void *argument;
eliminate_duplicates_arg(size_t size, my_hash_walk_action act, void* arg):
walk_action<T> *action;
T *argument;
eliminate_duplicates_arg(size_t size, walk_action<T> *act, T *arg):
action(act), argument(arg) { ids.reserve(size); }
};


template <typename T>
static my_bool eliminate_duplicates(rw_trx_hash_element_t *element,
eliminate_duplicates_arg *arg)
eliminate_duplicates_arg<T> *arg)
{
for (trx_ids_t::iterator it= arg->ids.begin(); it != arg->ids.end(); it++)
{
Expand All @@ -525,15 +530,16 @@ class rw_trx_hash_t
}


struct debug_iterator_arg
template <typename T> struct debug_iterator_arg
{
my_hash_walk_action action;
void *argument;
walk_action<T> *action;
T *argument;
};


template <typename T>
static my_bool debug_iterator(rw_trx_hash_element_t *element,
debug_iterator_arg *arg)
debug_iterator_arg<T> *arg)
{
mutex_enter(&element->mutex);
if (element->trx)
Expand Down Expand Up @@ -748,23 +754,28 @@ class rw_trx_hash_t
@retval 1 iteration was interrupted (action returned 1)
*/

int iterate(trx_t *caller_trx, my_hash_walk_action action, void *argument)
template <typename T>
int iterate(trx_t *caller_trx, walk_action<T> *action, T *argument= nullptr)
{
LF_PINS *pins= caller_trx ? get_pins(caller_trx) : lf_hash_get_pins(&hash);
ut_a(pins);
#ifdef UNIV_DEBUG
debug_iterator_arg debug_arg= { action, argument };
action= reinterpret_cast<my_hash_walk_action>(debug_iterator);
argument= &debug_arg;
debug_iterator_arg<T> debug_arg= { action, argument };
action= reinterpret_cast<decltype(action)>(debug_iterator<T>);
argument= reinterpret_cast<T*>(&debug_arg);
#endif
int res= lf_hash_iterate(&hash, pins, action, argument);
int res= lf_hash_iterate(&hash, pins,
reinterpret_cast<my_hash_walk_action>(action),
const_cast<void*>(static_cast<const void*>
(argument)));
if (!caller_trx)
lf_hash_put_pins(pins);
return res;
}


int iterate(my_hash_walk_action action, void *argument)
template <typename T>
int iterate(walk_action<T> *action, T *argument= nullptr)
{
return iterate(current_trx(), action, argument);
}
Expand All @@ -776,16 +787,17 @@ class rw_trx_hash_t
@sa iterate()
*/

int iterate_no_dups(trx_t *caller_trx, my_hash_walk_action action,
void *argument)
template <typename T>
int iterate_no_dups(trx_t *caller_trx, walk_action<T> *action,
T *argument= nullptr)
{
eliminate_duplicates_arg arg(size() + 32, action, argument);
return iterate(caller_trx, reinterpret_cast<my_hash_walk_action>
(eliminate_duplicates), &arg);
eliminate_duplicates_arg<T> arg(size() + 32, action, argument);
return iterate(caller_trx, eliminate_duplicates<T>, &arg);
}


int iterate_no_dups(my_hash_walk_action action, void *argument)
template <typename T>
int iterate_no_dups(walk_action<T> *action, T *argument= nullptr)
{
return iterate_no_dups(current_trx(), action, argument);
}
Expand Down Expand Up @@ -881,8 +893,7 @@ class trx_sys_t
trx_id_t get_min_trx_id()
{
trx_id_t id= get_max_trx_id();
rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
(get_min_trx_id_callback), &id);
rw_trx_hash.iterate(get_min_trx_id_callback, &id);
return id;
}

Expand Down Expand Up @@ -976,9 +987,7 @@ class trx_sys_t

ids->clear();
ids->reserve(rw_trx_hash.size() + 32);
rw_trx_hash.iterate(caller_trx,
reinterpret_cast<my_hash_walk_action>(copy_one_id),
&arg);
rw_trx_hash.iterate(caller_trx, copy_one_id, &arg);

*max_trx_id= arg.m_id;
*min_trx_no= arg.m_no;
Expand Down
12 changes: 3 additions & 9 deletions storage/innobase/lock/lock0lock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5157,8 +5157,7 @@ lock_validate()
lock_mutex_enter();

/* Validate table locks */
trx_sys.rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
(lock_validate_table_locks), 0);
trx_sys.rw_trx_hash.iterate(lock_validate_table_locks);

/* Iterate over all the record locks and validate the locks. We
don't want to hog the lock_sys_t::mutex. Release it during the
Expand Down Expand Up @@ -5452,9 +5451,7 @@ static void lock_rec_other_trx_holds_expl(trx_t *caller_trx, trx_t *trx,
lock_rec_other_trx_holds_expl_arg arg= { page_rec_get_heap_no(rec), block,
trx };
trx_sys.rw_trx_hash.iterate(caller_trx,
reinterpret_cast<my_hash_walk_action>
(lock_rec_other_trx_holds_expl_callback),
&arg);
lock_rec_other_trx_holds_expl_callback, &arg);
lock_mutex_exit();
}
}
Expand Down Expand Up @@ -6233,10 +6230,7 @@ lock_table_has_locks(

#ifdef UNIV_DEBUG
if (!has_locks) {
trx_sys.rw_trx_hash.iterate(
reinterpret_cast<my_hash_walk_action>
(lock_table_locks_lookup),
const_cast<dict_table_t*>(table));
trx_sys.rw_trx_hash.iterate(lock_table_locks_lookup, table);
}
#endif /* UNIV_DEBUG */

Expand Down
6 changes: 2 additions & 4 deletions storage/innobase/trx/trx0roll.cc
Original file line number Diff line number Diff line change
Expand Up @@ -717,8 +717,7 @@ void trx_roll_report_progress()
rows they modified. Numbers must be accurate, because only this
thread is allowed to touch recovered transactions. */
trx_sys.rw_trx_hash.iterate_no_dups(
reinterpret_cast<my_hash_walk_action>
(trx_roll_count_callback), &arg);
trx_roll_count_callback, &arg);

if (arg.n_rows > 0) {
service_manager_extend_timeout(
Expand Down Expand Up @@ -776,8 +775,7 @@ void trx_rollback_recovered(bool all)
other thread is allowed to modify or remove these transactions from
rw_trx_hash.
*/
trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
(trx_rollback_recovered_callback),
trx_sys.rw_trx_hash.iterate_no_dups(trx_rollback_recovered_callback,
&trx_list);

while (!trx_list.empty())
Expand Down
9 changes: 3 additions & 6 deletions storage/innobase/trx/trx0trx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2135,8 +2135,7 @@ int trx_recover_for_mysql(XID *xid_list, uint len)
ut_ad(len);

/* Fill xid_list with PREPARED transactions. */
trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
(trx_recover_for_mysql_callback), &arg);
trx_sys.rw_trx_hash.iterate_no_dups(trx_recover_for_mysql_callback, &arg);
if (arg.count)
{
ib::info() << arg.count
Expand All @@ -2146,8 +2145,7 @@ int trx_recover_for_mysql(XID *xid_list, uint len)
transactions twice, by first calling tc_log->open() and then
ha_recover() directly. */
if (arg.count <= len)
trx_sys.rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
(trx_recover_reset_callback), NULL);
trx_sys.rw_trx_hash.iterate(trx_recover_reset_callback);
}
return int(std::min(arg.count, len));
}
Expand Down Expand Up @@ -2201,8 +2199,7 @@ trx_t* trx_get_trx_by_xid(const XID* xid)
trx_get_trx_by_xid_callback_arg arg= { xid, 0 };

if (xid)
trx_sys.rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
(trx_get_trx_by_xid_callback), &arg);
trx_sys.rw_trx_hash.iterate(trx_get_trx_by_xid_callback, &arg);
return arg.trx;
}

Expand Down

0 comments on commit ccdfced

Please sign in to comment.