Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize store context queries, comments. #462

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading