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

Add mtr_buf_t::for_each_block_in_reverse() const

Avoid unnecessary creation of named objects for invoking
mtr_buf_t::for_each_block_in_reverse().
parent 93c84cc8
/*****************************************************************************
Copyright (c) 2013, 2016, 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
......@@ -371,6 +372,24 @@ class dyn_buf_t {
return(true);
}
/**
Iterate over all the blocks in reverse and call the iterator
@return false if iteration was terminated. */
template <typename Functor>
bool for_each_block_in_reverse(const Functor& functor) const
{
for (block_t* block = UT_LIST_GET_LAST(m_list);
block != NULL;
block = UT_LIST_GET_PREV(m_node, block)) {
if (!functor(block)) {
return(false);
}
}
return(true);
}
/**
@return the first block */
block_t* front()
......
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 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
......@@ -37,16 +37,43 @@ Created 11/26/1995 Heikki Tuuri
/** Iterate over a memo block in reverse. */
template <typename Functor>
struct Iterate {
struct CIterate {
CIterate() : functor() {}
/** Release specific object */
explicit Iterate(Functor& functor)
:
m_functor(functor)
CIterate(const Functor& functor) : functor(functor) {}
/** @return false if the functor returns false. */
bool operator()(mtr_buf_t::block_t* block) const
{
/* Do nothing */
const mtr_memo_slot_t* start =
reinterpret_cast<const mtr_memo_slot_t*>(
block->begin());
mtr_memo_slot_t* slot =
reinterpret_cast<mtr_memo_slot_t*>(
block->end());
ut_ad(!(block->used() % sizeof(*slot)));
while (slot-- != start) {
if (!functor(slot)) {
return(false);
}
}
return(true);
}
Functor functor;
};
template <typename Functor>
struct Iterate {
Iterate() : functor() {}
Iterate(const Functor& functor) : functor(functor) {}
/** @return false if the functor returns false. */
bool operator()(mtr_buf_t::block_t* block)
{
......@@ -62,7 +89,7 @@ struct Iterate {
while (slot-- != start) {
if (!m_functor(slot)) {
if (!functor(slot)) {
return(false);
}
}
......@@ -70,7 +97,7 @@ struct Iterate {
return(true);
}
Functor& m_functor;
Functor functor;
};
/** Find specific object */
......@@ -511,12 +538,7 @@ mtr_t::Command::release_resources()
/* Currently only used in commit */
ut_ad(m_impl->m_state == MTR_STATE_COMMITTING);
#ifdef UNIV_DEBUG
DebugCheck release;
Iterate<DebugCheck> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
#endif /* UNIV_DEBUG */
ut_d(m_impl->m_memo.for_each_block_in_reverse(CIterate<DebugCheck>()));
/* Reset the mtr buffers */
m_impl->m_log.erase();
......@@ -739,11 +761,10 @@ mtr_t::memo_release(const void* object, ulint type)
middle of a mini-transaction. */
ut_ad(!m_impl.m_modifications || type != MTR_MEMO_PAGE_X_FIX);
Find find(object, type);
Iterate<Find> iterator(find);
Iterate<Find> iteration(Find(object, type));
if (!m_impl.m_memo.for_each_block_in_reverse(iterator)) {
memo_slot_release(find.m_slot);
if (!m_impl.m_memo.for_each_block_in_reverse(iteration)) {
memo_slot_release(iteration.functor.m_slot);
return(true);
}
......@@ -763,11 +784,10 @@ mtr_t::release_page(const void* ptr, mtr_memo_type_t type)
middle of a mini-transaction. */
ut_ad(!m_impl.m_modifications || type != MTR_MEMO_PAGE_X_FIX);
FindPage find(ptr, type);
Iterate<FindPage> iterator(find);
Iterate<FindPage> iteration(FindPage(ptr, type));
if (!m_impl.m_memo.for_each_block_in_reverse(iterator)) {
memo_slot_release(find.get_slot());
if (!m_impl.m_memo.for_each_block_in_reverse(iteration)) {
memo_slot_release(iteration.functor.get_slot());
return;
}
......@@ -891,10 +911,7 @@ mtr_t::Command::finish_write(
void
mtr_t::Command::release_all()
{
ReleaseAll release;
Iterate<ReleaseAll> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
m_impl->m_memo.for_each_block_in_reverse(CIterate<ReleaseAll>());
/* Note that we have released the latches. */
m_locks_released = 1;
......@@ -904,10 +921,7 @@ mtr_t::Command::release_all()
void
mtr_t::Command::release_latches()
{
ReleaseLatches release;
Iterate<ReleaseLatches> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
m_impl->m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>());
/* Note that we have released the latches. */
m_locks_released = 1;
......@@ -917,10 +931,10 @@ mtr_t::Command::release_latches()
void
mtr_t::Command::release_blocks()
{
ReleaseBlocks release(m_start_lsn, m_end_lsn, m_impl->m_flush_observer);
Iterate<ReleaseBlocks> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
m_impl->m_memo.for_each_block_in_reverse(
CIterate<const ReleaseBlocks>(
ReleaseBlocks(m_start_lsn, m_end_lsn,
m_impl->m_flush_observer)));
}
/** Write the redo log record, add dirty pages to the flush list and release
......@@ -997,10 +1011,8 @@ mtr_t::memo_contains(
const void* object,
ulint type)
{
Find find(object, type);
Iterate<Find> iterator(find);
if (memo->for_each_block_in_reverse(iterator)) {
Iterate<Find> iteration(Find(object, type));
if (memo->for_each_block_in_reverse(iteration)) {
return(false);
}
......@@ -1089,10 +1101,8 @@ mtr_t::memo_contains_flagged(const void* ptr, ulint flags) const
ut_ad(m_impl.m_magic_n == MTR_MAGIC_N);
ut_ad(is_committing() || is_active());
FlaggedCheck check(ptr, flags);
Iterate<FlaggedCheck> iterator(check);
return(!m_impl.m_memo.for_each_block_in_reverse(iterator));
return !m_impl.m_memo.for_each_block_in_reverse(
CIterate<FlaggedCheck>(FlaggedCheck(ptr, flags)));
}
/** Check if memo contains the given page.
......@@ -1106,11 +1116,9 @@ mtr_t::memo_contains_page_flagged(
const byte* ptr,
ulint flags) const
{
FindPage check(ptr, flags);
Iterate<FindPage> iterator(check);
return(m_impl.m_memo.for_each_block_in_reverse(iterator)
? NULL : check.get_block());
Iterate<FindPage> iteration(FindPage(ptr, flags));
return m_impl.m_memo.for_each_block_in_reverse(iteration)
? NULL : iteration.functor.get_block();
}
/** Mark the given latched page as modified.
......
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