Skip to content

Commit

Permalink
Normalize store context queries, comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed May 6, 2024
1 parent 2ee84f6 commit 20e86f4
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 126 deletions.
4 changes: 2 additions & 2 deletions include/bitcoin/database/impl/query/query.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ CLASS::query(Store& value) NOEXCEPT
TEMPLATE
bool CLASS::is_full() const NOEXCEPT
{
return store_.get_error(error::disk_full);
return store_.is_error(error::disk_full);
}

TEMPLATE
bool CLASS::is_fault() const NOEXCEPT
{
return !!store_.get_first_error();
return !!store_.get_fault();
}

} // namespace database
Expand Down
248 changes: 131 additions & 117 deletions include/bitcoin/database/impl/store.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -393,128 +393,20 @@ code CLASS::close(const event_handler& handler) NOEXCEPT

if (!ec) ec = unload_close(handler);

// unlock errors override ec, fault overrides unlock errors.
const auto fault = get_first_error() && !get_error(error::disk_full);
if (!fault && !flush_lock_.try_unlock()) ec = error::flush_unlock;
if (!process_lock_.try_unlock()) ec = error::process_unlock;
if (fault) ec = error::integrity;
transactor_mutex_.unlock();
return ec;
}
// unlock errors override ec.
if (!process_lock_.try_unlock())
ec = error::process_unlock;

TEMPLATE
const typename CLASS::transactor CLASS::get_transactor() NOEXCEPT
{
return transactor{ transactor_mutex_ };
}
// fault overrides unlock errors and leaves behind flush_lock.
if (get_fault())
ec = error::integrity;
else if (!flush_lock_.try_unlock())
ec = error::flush_unlock;

TEMPLATE
code CLASS::get_first_error() const NOEXCEPT
{
code ec{};
if ((ec = header_body_.get_error())) return ec;
if ((ec = input_body_.get_error())) return ec;
if ((ec = output_body_.get_error())) return ec;
if ((ec = point_body_.get_error())) return ec;
if ((ec = puts_body_.get_error())) return ec;
if ((ec = spend_body_.get_error())) return ec;
if ((ec = tx_body_.get_error())) return ec;
if ((ec = txs_body_.get_error())) return ec;
if ((ec = candidate_body_.get_error())) return ec;
if ((ec = confirmed_body_.get_error())) return ec;
if ((ec = strong_tx_body_.get_error())) return ec;
if ((ec = validated_bk_body_.get_error())) return ec;
if ((ec = validated_tx_body_.get_error())) return ec;
if ((ec = address_body_.get_error())) return ec;
if ((ec = neutrino_body_.get_error())) return ec;
////if ((ec = bootstrap_body_.get_error())) return ec;
////if ((ec = buffer_body_.get_error())) return ec;
transactor_mutex_.unlock();
return ec;
}

TEMPLATE
bool CLASS::get_error(const code& ec) const NOEXCEPT
{
// A disk full error will not leave a flush lock, but others will.
// There may be other error codes as well so check all.

bool found{};
const auto match = [&ec, &found](const auto& storage) NOEXCEPT
{
const auto error = storage.get_error();
if (error == ec) found = true;
return !error || found;
};

return match(header_body_)
&& match(input_body_)
&& match(output_body_)
&& match(point_body_)
&& match(puts_body_)
&& match(spend_body_)
&& match(tx_body_)
&& match(txs_body_)
&& match(candidate_body_)
&& match(confirmed_body_)
&& match(strong_tx_body_)
&& match(validated_bk_body_)
&& match(validated_tx_body_)
&& match(address_body_)
&& match(neutrino_body_)
////&& match(bootstrap_body_)
////&& match(buffer_body_)
&& found;
}

TEMPLATE
void CLASS::clear_error() NOEXCEPT
{
header_body_.clear_error();
input_body_.clear_error();
output_body_.clear_error();
point_body_.clear_error();
puts_body_.clear_error();
spend_body_.clear_error();
tx_body_.clear_error();
txs_body_.clear_error();
candidate_body_.clear_error();
confirmed_body_.clear_error();
strong_tx_body_.clear_error();
validated_bk_body_.clear_error();
validated_tx_body_.clear_error();
address_body_.clear_error();
neutrino_body_.clear_error();
////bootstrap_body_.clear_error();
////buffer_body_.clear_error();
}

TEMPLATE
void CLASS::report_errors(const error_handler& handler) NOEXCEPT
{
const auto report = [&handler](const auto& storage, table_t table) NOEXCEPT
{
handler(storage.get_error(), table);
};

report(header_body_, table_t::header_body);
report(input_body_, table_t::input_body);
report(output_body_, table_t::output_body);
report(point_body_, table_t::point_body);
report(puts_body_, table_t::puts_body);
report(spend_body_, table_t::spend_body);
report(tx_body_, table_t::tx_body);
report(txs_body_, table_t::txs_body);
report(candidate_body_, table_t::candidate_body);
report(confirmed_body_, table_t::confirmed_body);
report(strong_tx_body_, table_t::strong_tx_body);
report(validated_bk_body_, table_t::validated_bk_body);
report(validated_tx_body_, table_t::validated_tx_body);
report(address_body_, table_t::address_body);
report(neutrino_body_, table_t::neutrino_body);
////report(bootstrap_body_, table_t::bootstrap_body);
////report(buffer_body_, table_t::buffer_body);
}

// protected
// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -968,6 +860,128 @@ code CLASS::restore(const event_handler& handler) NOEXCEPT
return ec;
}

// context
// ----------------------------------------------------------------------------

TEMPLATE
const typename CLASS::transactor CLASS::get_transactor() NOEXCEPT
{
return transactor{ transactor_mutex_ };
}

TEMPLATE
code CLASS::get_fault() const NOEXCEPT
{
const auto fault = [](const auto& storage) NOEXCEPT
{
const auto ec = storage.get_error();
return ec == error::disk_full ? error::success : ec;
};

code ec{};
if ((ec = fault(header_body_))) return ec;
if ((ec = fault(input_body_))) return ec;
if ((ec = fault(output_body_))) return ec;
if ((ec = fault(point_body_))) return ec;
if ((ec = fault(puts_body_))) return ec;
if ((ec = fault(spend_body_))) return ec;
if ((ec = fault(tx_body_))) return ec;
if ((ec = fault(txs_body_))) return ec;
if ((ec = fault(candidate_body_))) return ec;
if ((ec = fault(confirmed_body_))) return ec;
if ((ec = fault(strong_tx_body_))) return ec;
if ((ec = fault(validated_bk_body_))) return ec;
if ((ec = fault(validated_tx_body_))) return ec;
if ((ec = fault(address_body_))) return ec;
if ((ec = fault(neutrino_body_))) return ec;
////if ((ec = fault(bootstrap_body_))) return ec;
////if ((ec = fault(buffer_body_))) return ec;
return ec;
}

TEMPLATE
bool CLASS::is_error(const code& ec) const NOEXCEPT
{
// A disk full error will not leave a flush lock, but others will.
// There may be other error codes as well so check all.

bool found{};
const auto match = [&ec, &found](const auto& storage) NOEXCEPT
{
const auto error = storage.get_error();
if (error == ec) found = true;
return !error || found;
};

return match(header_body_)
&& match(input_body_)
&& match(output_body_)
&& match(point_body_)
&& match(puts_body_)
&& match(spend_body_)
&& match(tx_body_)
&& match(txs_body_)
&& match(candidate_body_)
&& match(confirmed_body_)
&& match(strong_tx_body_)
&& match(validated_bk_body_)
&& match(validated_tx_body_)
&& match(address_body_)
&& match(neutrino_body_)
////&& match(bootstrap_body_)
////&& match(buffer_body_)
&& found;
}

TEMPLATE
void CLASS::clear_errors() NOEXCEPT
{
header_body_.clear_error();
input_body_.clear_error();
output_body_.clear_error();
point_body_.clear_error();
puts_body_.clear_error();
spend_body_.clear_error();
tx_body_.clear_error();
txs_body_.clear_error();
candidate_body_.clear_error();
confirmed_body_.clear_error();
strong_tx_body_.clear_error();
validated_bk_body_.clear_error();
validated_tx_body_.clear_error();
address_body_.clear_error();
neutrino_body_.clear_error();
////bootstrap_body_.clear_error();
////buffer_body_.clear_error();
}

TEMPLATE
void CLASS::report_errors(const error_handler& handler) NOEXCEPT
{
const auto report = [&handler](const auto& storage, table_t table) NOEXCEPT
{
handler(storage.get_error(), table);
};

report(header_body_, table_t::header_body);
report(input_body_, table_t::input_body);
report(output_body_, table_t::output_body);
report(point_body_, table_t::point_body);
report(puts_body_, table_t::puts_body);
report(spend_body_, table_t::spend_body);
report(tx_body_, table_t::tx_body);
report(txs_body_, table_t::txs_body);
report(candidate_body_, table_t::candidate_body);
report(confirmed_body_, table_t::confirmed_body);
report(strong_tx_body_, table_t::strong_tx_body);
report(validated_bk_body_, table_t::validated_bk_body);
report(validated_tx_body_, table_t::validated_tx_body);
report(address_body_, table_t::address_body);
report(neutrino_body_, table_t::neutrino_body);
////report(bootstrap_body_, table_t::bootstrap_body);
////report(buffer_body_, table_t::buffer_body);
}

BC_POP_WARNING()

} // namespace database
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class query
/// True if disk is full and no other store error condition.
bool is_full() const NOEXCEPT;

/// True if there is any store error condition.
/// True if there is any store error condition (excludes error::disk_full).
bool is_fault() const NOEXCEPT;

/// Initialization (natural-keyed).
Expand Down
19 changes: 14 additions & 5 deletions include/bitcoin/database/store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class store
/// Construct a store from settings.
store(const settings& config) NOEXCEPT;

/// Methods.
/// -----------------------------------------------------------------------

/// Create the set of empty files (from unloaded).
code create(const event_handler& handler) NOEXCEPT;

Expand All @@ -65,21 +68,27 @@ class store
/// Unload and close the set of tables, clear locks.
code close(const event_handler& handler) NOEXCEPT;

/// Context.
/// -----------------------------------------------------------------------

/// Get a transactor object.
const transactor get_transactor() NOEXCEPT;

/// Detect the first error condition.
code get_first_error() const NOEXCEPT;
/// Detect the first error condition (excludes error::disk_full).
code get_fault() const NOEXCEPT;

/// Detect the specified error condition (exclusive).
bool get_error(const code& ec) const NOEXCEPT;
/// Detect the exclusive existence of the specified error condition.
bool is_error(const code& ec) const NOEXCEPT;

/// Clear all error conditions.
void clear_error() NOEXCEPT;
void clear_errors() NOEXCEPT;

/// Dump all error conditions to error handler.
void report_errors(const error_handler& handler) NOEXCEPT;

/// Tables.
/// -----------------------------------------------------------------------

/// Archives.
table::header header;
table::input input;
Expand Down
2 changes: 1 addition & 1 deletion test/store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(store__get_error__disk_full__false)
{
const settings configuration{};
test::map_store instance{ configuration };
BOOST_REQUIRE(!instance.get_error(error::disk_full));
BOOST_REQUIRE(!instance.is_error(error::disk_full));
}

// create
Expand Down

0 comments on commit 20e86f4

Please sign in to comment.