Skip to content

Commit

Permalink
Optimize using new hashmap.find(key).
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed Jun 11, 2024
1 parent af584ec commit 51ab282
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 59 deletions.
26 changes: 19 additions & 7 deletions include/bitcoin/database/impl/query/archive.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ TEMPLATE
inline bool CLASS::is_malleable64(const header_link& link) const NOEXCEPT
{
table::txs::get_malleable txs{};
return store_.txs.get(to_txs_link(link), txs) && txs.malleable;
return store_.txs.find(link, txs) && txs.malleable;
}

TEMPLATE
inline bool CLASS::is_associated(const header_link& link) const NOEXCEPT
{
table::txs::get_associated txs{};
return store_.txs.get(to_txs_link(link), txs) && txs.associated;
return store_.txs.find(link, txs) && txs.associated;
}

TEMPLATE
Expand Down Expand Up @@ -283,7 +283,7 @@ bool CLASS::populate_with_metadata(const block& block) const NOEXCEPT
TEMPLATE
hashes CLASS::get_tx_keys(const header_link& link) const NOEXCEPT
{
const auto tx_fks = to_txs(link);
const auto tx_fks = to_transactions(link);
if (tx_fks.empty())
return {};

Expand Down Expand Up @@ -314,9 +314,21 @@ inline hash_digest CLASS::get_tx_key(const tx_link& link) const NOEXCEPT
return store_.tx.get_key(link);
}

TEMPLATE
bool CLASS::get_height(size_t& out, const hash_digest& key) const NOEXCEPT
{
const auto height = get_height(key);
if (height >= height_link::terminal)
return false;

out = system::possible_narrow_cast<size_t>(height.value);
return true;
}

TEMPLATE
bool CLASS::get_height(size_t& out, const header_link& link) const NOEXCEPT
{
// Use get_height(..., key) in place of get(to_header(key)).
const auto height = get_height(link);
if (height >= height_link::terminal)
return false;
Expand All @@ -343,7 +355,7 @@ bool CLASS::get_tx_position(size_t& out, const tx_link& link) const NOEXCEPT

// False return below implies an integrity error (tx should be indexed).
table::txs::get_position txs{ {}, link };
if (!store_.txs.get(to_txs_link(block_fk), txs))
if (!store_.txs.find(block_fk, txs))
return false;

out = txs.position;
Expand Down Expand Up @@ -430,7 +442,7 @@ typename CLASS::transactions_ptr CLASS::get_transactions(
const header_link& link) const NOEXCEPT
{
using namespace system;
const auto txs = to_txs(link);
const auto txs = to_transactions(link);
if (txs.empty())
return {};

Expand Down Expand Up @@ -482,7 +494,7 @@ TEMPLATE
size_t CLASS::get_block_size(const header_link& link) const NOEXCEPT
{
table::txs::get_block_size txs{};
return store_.txs.get(to_txs_link(link), txs) ? txs.wire : zero;
return store_.txs.find(link, txs) ? txs.wire : zero;
}

TEMPLATE
Expand Down Expand Up @@ -997,7 +1009,7 @@ code CLASS::set_code(txs_link& out_fk, const transactions& txs,
////// This is only fully effective if there is a single database thread.
////// Guard must be lifted for an existing top malleable association so
////// that a non-malleable association may be accomplished.
////out_fk = to_txs_link(key);
////out_fk = to_txs(key);
////if (!out_fk.is_terminal() && !is_malleable(key))
//// return error::success;

Expand Down
34 changes: 24 additions & 10 deletions include/bitcoin/database/impl/query/confirm.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ namespace database {
// ----------------------------------------------------------------------------
// Not for use in validatation (2 additional gets) or confirmation (height).

// protected
TEMPLATE
height_link CLASS::get_height(const hash_digest& key) const NOEXCEPT
{
table::header::get_height header{};
if (!store_.header.find(key, header))
return {};

return header.height;
}

// protected
TEMPLATE
height_link CLASS::get_height(const header_link& link) const NOEXCEPT
Expand Down Expand Up @@ -236,14 +247,15 @@ TEMPLATE
inline error::error_t CLASS::spent_prevout(const foreign_point& point,
const tx_link& self) const NOEXCEPT
{
// Modest (1.3%) after head optimization.
// (2.94%)
auto it = store_.spend.it(point);
if (!it)
return error::success;

table::spend::get_parent spend{};
do
{
// (0.38%)
if (!store_.spend.get(it, spend))
return error::integrity;

Expand All @@ -257,7 +269,7 @@ inline error::error_t CLASS::spent_prevout(const foreign_point& point,
if (!to_block(spend.parent_fk).is_terminal())
return error::confirmed_double_spend;
}
// Expensive (41%).
// Expensive (31.19%).
// Iteration exists because we allow double spending, and by design cannot
// preclude it because we download and index concurrently before confirm.
while (it.advance());
Expand Down Expand Up @@ -328,32 +340,34 @@ code CLASS::block_confirmable(const header_link& link) const NOEXCEPT
if (!get_context(ctx, link))
return error::integrity;

const auto txs = to_txs(link);
// (0.07%)
const auto txs = to_transactions(link);
if (txs.empty())
return error::success;

// Cheap (0.2%) because !bip30.
// (0.11%) because !bip30.
code ec{};
if ((ec = unspent_duplicates(txs.front(), ctx)))
return ec;

// (0.33%)
uint32_t version{};
table::spend::get_prevout_sequence spend{};
for (auto tx = std::next(txs.begin()); tx != txs.end(); ++tx)
{
// Modest (1.4% tx.get, 1% puts.get - to_tx_spends), reduce collision.
// (4.71%) tx.get, puts.get, reduce collision.
for (const auto& spend_fk: to_tx_spends(version, *tx))
{
// Modest, (1.4% spend.get), reduce collision.
// (3.65%) spend.get, reduce collision.
if (!store_.spend.get(spend_fk, spend))
return error::integrity;

// Expensive (11%).
// (33.42%)
if ((ec = unspendable_prevout(spend.point_fk, spend.sequence,
version, ctx)))
return ec;

// Expensive (44%).
// (34.74%)
if ((ec = spent_prevout(spend.prevout(), *tx)))
return ec;
}
Expand Down Expand Up @@ -390,7 +404,7 @@ bool CLASS::is_strong(const header_link& link) const NOEXCEPT
TEMPLATE
bool CLASS::set_strong(const header_link& link) NOEXCEPT
{
const auto txs = to_txs(link);
const auto txs = to_transactions(link);
if (txs.empty())
return false;

Expand All @@ -405,7 +419,7 @@ bool CLASS::set_strong(const header_link& link) NOEXCEPT
TEMPLATE
bool CLASS::set_unstrong(const header_link& link) NOEXCEPT
{
const auto txs = to_txs(link);
const auto txs = to_transactions(link);
if (txs.empty())
return false;

Expand Down
6 changes: 3 additions & 3 deletions include/bitcoin/database/impl/query/optional.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ TEMPLATE
bool CLASS::get_filter(filter& out, const header_link& link) const NOEXCEPT
{
table::neutrino::get_filter neutrino{};
if (!store_.neutrino.get(store_.neutrino.first(link), neutrino))
if (!store_.neutrino.find(link, neutrino))
return false;

out = std::move(neutrino.filter);
Expand All @@ -191,7 +191,7 @@ bool CLASS::get_filter_head(hash_digest& out,
const header_link& link) const NOEXCEPT
{
table::neutrino::get_head neutrino{};
if (!store_.neutrino.get(store_.neutrino.first(link), neutrino))
if (!store_.neutrino.find(link, neutrino))
return false;

out = std::move(neutrino.filter_head);
Expand Down Expand Up @@ -229,7 +229,7 @@ bool CLASS::set_filter(const header_link& link, const hash_digest& filter_head,
//// const tx_link& link) const NOEXCEPT
////{
//// table::buffer::slab_ptr buffer{};
//// if (!store_.buffer.get(store_.buffer.first(link), buffer))
//// if (!store_.buffer.find(link, buffer))
//// return {};
////
//// return buffer.tx;
Expand Down
41 changes: 28 additions & 13 deletions include/bitcoin/database/impl/query/translate.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,35 @@ inline header_link CLASS::to_confirmed(size_t height) const NOEXCEPT
TEMPLATE
inline header_link CLASS::to_header(const hash_digest& key) const NOEXCEPT
{
// Use header.find(key) in place of get(to_header(key)).
return store_.header.first(key);
}

TEMPLATE
inline point_link CLASS::to_point(const hash_digest& key) const NOEXCEPT
{
// Use point.find(key) in place of get(to_point(key)).
return store_.point.first(key);
}

TEMPLATE
inline tx_link CLASS::to_tx(const hash_digest& key) const NOEXCEPT
{
// Use tx.find(key) in place of get(to_tx(key)).
return store_.tx.first(key);
}

TEMPLATE
inline txs_link CLASS::to_txs_link(const header_link& key) const NOEXCEPT
inline txs_link CLASS::to_txs(const header_link& key) const NOEXCEPT
{
// Use txs.find(key) in place of get(to_txs(key)).
return store_.txs.first(key);
}

TEMPLATE
inline filter_link CLASS::to_filter(const header_link& key) const NOEXCEPT
{
// Use neutrino.find(key) in place of get(to_filter(key)).
return store_.neutrino.first(key);
}

Expand Down Expand Up @@ -196,13 +201,15 @@ header_link CLASS::to_parent(const header_link& link) const NOEXCEPT
TEMPLATE
header_link CLASS::to_block(const tx_link& link) const NOEXCEPT
{
// Expensive (3.8%) from block_confirmable->to_strong.
// (10.99%) from block_confirmable->unspendable_prevout->to_strong->to_block.

// No to_strong_tx_link() because no type for strong_tx_link.
const auto to_strong_tx_link = store_.strong_tx.first(link);
// (8.25%)
////const auto to_strong_tx_link = store_.strong_tx.first(link);

// (2.68%)
table::strong_tx::record strong{};
if (!store_.strong_tx.get(to_strong_tx_link, strong))
////if (!store_.strong_tx.get(to_strong_tx_link, strong))
if (!store_.strong_tx.find(link, strong))
return {};

// Terminal implies not strong (false).
Expand All @@ -219,7 +226,7 @@ header_link CLASS::to_block(const tx_link& link) const NOEXCEPT
TEMPLATE
inline strong_pair CLASS::to_strong(const hash_digest& tx_hash) const NOEXCEPT
{
// Expensive (4.6%) from block_confirmable, reduce collision.
// (14.21%) from block_confirmable, reduce collision.
auto it = store_.tx.it(tx_hash);
strong_pair strong{ {}, it.self() };
if (!it)
Expand All @@ -229,11 +236,12 @@ inline strong_pair CLASS::to_strong(const hash_digest& tx_hash) const NOEXCEPT
{
strong.tx = it.self();

// Expensive (3.8%) from block_confirmable.
// (10.99%) from block_confirmable.
strong.block = to_block(strong.tx);
if (!strong.block.is_terminal())
return strong;
}
// (0.28%)
while (it.advance());
return strong;
}
Expand Down Expand Up @@ -444,12 +452,17 @@ TEMPLATE
spend_links CLASS::to_tx_spends(uint32_t& version,
const tx_link& link) const NOEXCEPT
{
// (4.71%) from block_confirmable.

// (2.53%)
table::transaction::get_version_puts tx{};
if (!store_.tx.get(link, tx))
return {};

version = tx.version;
table::puts::get_spends puts{};

// (2.1%)
puts.spend_fks.resize(tx.ins_count);
if (!store_.puts.get(tx.puts_fk, puts))
return {};
Expand All @@ -461,10 +474,11 @@ spend_links CLASS::to_tx_spends(uint32_t& version,
// ----------------------------------------------------------------------------

TEMPLATE
tx_links CLASS::to_txs(const header_link& link) const NOEXCEPT
tx_links CLASS::to_transactions(const header_link& link) const NOEXCEPT
{
table::txs::slab txs{};
if (!store_.txs.get(to_txs_link(link), txs))
////if (!store_.txs.get(to_txs(link), txs))
if (!store_.txs.find(link, txs))
return {};

return std::move(txs.tx_fks);
Expand All @@ -474,7 +488,8 @@ TEMPLATE
tx_link CLASS::to_coinbase(const header_link& link) const NOEXCEPT
{
table::txs::get_coinbase txs{};
if (!store_.txs.get(to_txs_link(link), txs))
////if (!store_.txs.get(to_txs(link), txs))
if (!store_.txs.find(link, txs))
return {};

return txs.coinbase_fk;
Expand All @@ -484,7 +499,7 @@ TEMPLATE
spend_links CLASS::to_non_coinbase_spends(
const header_link& link) const NOEXCEPT
{
const auto txs = to_txs(link);
const auto txs = to_transactions(link);
if (txs.size() <= one)
return {};

Expand All @@ -503,7 +518,7 @@ TEMPLATE
spend_links CLASS::to_block_spends(const header_link& link) const NOEXCEPT
{
spend_links spends{};
const auto txs = to_txs(link);
const auto txs = to_transactions(link);

for (const auto& tx: txs)
{
Expand All @@ -518,7 +533,7 @@ TEMPLATE
output_links CLASS::to_block_outputs(const header_link& link) const NOEXCEPT
{
output_links outputs{};
const auto txs = to_txs(link);
const auto txs = to_transactions(link);

for (const auto& tx: txs)
{
Expand Down
Loading

0 comments on commit 51ab282

Please sign in to comment.