Commit 5fb4c0a8 authored by Marko Mäkelä's avatar Marko Mäkelä

Clean up ut_list

ut_list_validate(), ut_list_map(): Add variants with const Functor&
so that these functions can be called with an rvalue.

Remove wrapper macros, and add #ifdef UNIV_DEBUG around debug-only code.
parent bdd6e33f
......@@ -177,11 +177,11 @@ struct CheckZipFree {
void operator()(const buf_buddy_free_t* elem) const
{
ut_a(buf_buddy_stamp_is_free(elem));
ut_a(elem->stamp.size <= m_i);
ut_ad(buf_buddy_stamp_is_free(elem));
ut_ad(elem->stamp.size <= m_i);
}
ulint m_i;
const ulint m_i;
};
/** Validate a buddy list.
......@@ -193,8 +193,7 @@ buf_buddy_list_validate(
const buf_pool_t* buf_pool,
ulint i)
{
CheckZipFree check(i);
ut_list_validate(buf_pool->zip_free[i], check);
ut_list_validate(buf_pool->zip_free[i], CheckZipFree(i));
}
/**********************************************************************//**
......
......@@ -3533,7 +3533,7 @@ buf_flush_request_force(
/** Functor to validate the flush list. */
struct Check {
void operator()(const buf_page_t* elem)
void operator()(const buf_page_t* elem) const
{
ut_a(elem->in_flush_list);
}
......@@ -3550,11 +3550,10 @@ buf_flush_validate_low(
{
buf_page_t* bpage;
const ib_rbt_node_t* rnode = NULL;
Check check;
ut_ad(buf_flush_list_mutex_own(buf_pool));
ut_list_validate(buf_pool->flush_list, check);
ut_list_validate(buf_pool->flush_list, Check());
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
......
......@@ -5327,7 +5327,7 @@ fil_validate(void)
ut_a(fil_system->n_open == n_open);
UT_LIST_CHECK(fil_system->LRU);
ut_list_validate(fil_system->LRU);
for (fil_node = UT_LIST_GET_FIRST(fil_system->LRU);
fil_node != 0;
......
......@@ -2423,8 +2423,7 @@ struct CheckInLRUList {
static void validate(const buf_pool_t* buf_pool)
{
CheckInLRUList check;
ut_list_validate(buf_pool->LRU, check);
ut_list_validate(buf_pool->LRU, CheckInLRUList());
}
};
......@@ -2437,8 +2436,7 @@ struct CheckInFreeList {
static void validate(const buf_pool_t* buf_pool)
{
CheckInFreeList check;
ut_list_validate(buf_pool->free, check);
ut_list_validate(buf_pool->free, CheckInFreeList());
}
};
......@@ -2451,8 +2449,8 @@ struct CheckUnzipLRUAndLRUList {
static void validate(const buf_pool_t* buf_pool)
{
CheckUnzipLRUAndLRUList check;
ut_list_validate(buf_pool->unzip_LRU, check);
ut_list_validate(buf_pool->unzip_LRU,
CheckUnzipLRUAndLRUList());
}
};
#endif /* UNIV_DEBUG || defined UNIV_BUF_DEBUG */
......
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, 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
......@@ -426,24 +427,19 @@ Gets the last node in a two-way list.
@return last node, or NULL if the list is empty */
#define UT_LIST_GET_LAST(BASE) (BASE).end
struct NullValidate { void operator()(const void* elem) { } };
struct NullValidate { void operator()(const void*) const {} };
/********************************************************************//**
Iterate over all the elements and call the functor for each element.
/** Iterate over all the elements and call the functor for each element.
@param[in] list base node (not a pointer to it)
@param[in,out] functor Functor that is called for each element in the list */
template <typename List, class Functor>
void
ut_list_map(
const List& list,
Functor& functor)
inline void ut_list_map(const List& list, Functor& functor)
{
ulint count = 0;
UT_LIST_IS_INITIALISED(list);
for (typename List::elem_type* elem = list.start;
elem != 0;
for (typename List::elem_type* elem = list.start; elem;
elem = (elem->*list.node).next, ++count) {
functor(elem);
......@@ -452,32 +448,50 @@ ut_list_map(
ut_a(count == list.count);
}
template <typename List>
void
ut_list_reverse(List& list)
/** Iterate over all the elements and call the functor for each element.
@param[in] list base node (not a pointer to it)
@param[in] functor Functor that is called for each element in the list */
template <typename List, class Functor>
inline void ut_list_map(const List& list, const Functor& functor)
{
ulint count = 0;
UT_LIST_IS_INITIALISED(list);
for (typename List::elem_type* elem = list.start;
for (typename List::elem_type* elem = list.start; elem;
elem = (elem->*list.node).next, ++count) {
functor(elem);
}
ut_a(count == list.count);
}
/** Check the consistency of a doubly linked list.
@param[in] list base node (not a pointer to it)
@param[in,out] functor Functor that is called for each element in the list */
template <typename List, class Functor>
void ut_list_validate(const List& list, Functor& functor)
{
ut_list_map(list, functor);
/* Validate the list backwards. */
ulint count = 0;
for (typename List::elem_type* elem = list.end;
elem != 0;
elem = (elem->*list.node).prev) {
(elem->*list.node).reverse();
++count;
}
list.reverse();
ut_a(count == list.count);
}
#define UT_LIST_REVERSE(LIST) ut_list_reverse(LIST)
/********************************************************************//**
Checks the consistency of a two-way list.
/** Check the consistency of a doubly linked list.
@param[in] list base node (not a pointer to it)
@param[in,out] functor Functor that is called for each element in the list */
@param[in] functor Functor that is called for each element in the list */
template <typename List, class Functor>
void
ut_list_validate(
const List& list,
Functor& functor)
inline void ut_list_validate(const List& list, const Functor& functor)
{
ut_list_map(list, functor);
......@@ -493,12 +507,42 @@ ut_list_validate(
ut_a(count == list.count);
}
/** Check the consistency of a two-way list.
@param[in] LIST base node reference */
#define UT_LIST_CHECK(LIST) do { \
NullValidate nullV; \
ut_list_validate(LIST, nullV); \
} while (0)
template <typename List>
inline void ut_list_validate(const List& list)
{
ut_list_validate(list, NullValidate());
}
#ifdef UNIV_DEBUG
template <typename List>
inline void ut_list_reverse(List& list)
{
UT_LIST_IS_INITIALISED(list);
for (typename List::elem_type* elem = list.start;
elem != 0;
elem = (elem->*list.node).prev) {
(elem->*list.node).reverse();
}
list.reverse();
}
/** Check if the given element exists in the list.
@param[in,out] list the list object
@param[in] elem the element of the list which will be checked */
template <typename List>
inline bool ut_list_exists(const List& list, typename List::elem_type* elem)
{
for (typename List::elem_type* e1 = UT_LIST_GET_FIRST(list); e1;
e1 = (e1->*list.node).next) {
if (elem == e1) {
return true;
}
}
return false;
}
#endif
/** Move the given element to the beginning of the list.
@param[in,out] list the list object
......@@ -519,28 +563,6 @@ ut_list_move_to_front(
}
#ifdef UNIV_DEBUG
/** Check if the given element exists in the list.
@param[in,out] list the list object
@param[in] elem the element of the list which will be checked */
template <typename List>
bool
ut_list_exists(
List& list,
typename List::elem_type* elem)
{
typename List::elem_type* e1;
for (e1 = UT_LIST_GET_FIRST(list); e1 != NULL;
e1 = (e1->*list.node).next) {
if (elem == e1) {
return(true);
}
}
return(false);
}
#endif
#define UT_LIST_MOVE_TO_FRONT(LIST, ELEM) \
ut_list_move_to_front(LIST, ELEM)
#endif /* ut0lst.h */
......@@ -2738,7 +2738,7 @@ lock_move_granted_locks_to_front(
if (!lock->is_waiting()) {
lock_t* prev = UT_LIST_GET_PREV(trx_locks, lock);
ut_a(prev);
UT_LIST_MOVE_TO_FRONT(lock_list, lock);
ut_list_move_to_front(lock_list, lock);
lock = prev;
}
}
......@@ -2826,7 +2826,7 @@ lock_move_reorganize_page(
lock_move_granted_locks_to_front(old_locks);
DBUG_EXECUTE_IF("do_lock_reverse_page_reorganize",
UT_LIST_REVERSE(old_locks););
ut_list_reverse(old_locks););
for (lock = UT_LIST_GET_FIRST(old_locks); lock;
lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
......
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