2222#include < atomic>
2323#include < algorithm>
2424#include < iterator>
25- #include < memory>
2625#include < numeric>
2726#include < utility>
2827#include < bitcoin/database/define.hpp>
2928
30- // virtual_size
31- // ----------------------------------------------------------------------------
32-
3329namespace libbitcoin {
3430namespace database {
3531
32+ // virtual_size
33+ // ----------------------------------------------------------------------------
34+
3635TEMPLATE
3736bool CLASS::get_tx_virtual_size (size_t & out,
3837 const tx_link& link) const NOEXCEPT
@@ -63,70 +62,36 @@ bool CLASS::get_block_virtual_size(size_t& out,
6362TEMPLATE
6463bool CLASS::get_tx_fees (fee_rate& out, const tx_link& link) const NOEXCEPT
6564{
66- #if defined(SLOW_FEES)
65+ // This is somehow ~15-20% less efficient.
66+ // //return get_tx_virtual_size(out.bytes, link) && get_tx_fee(out.fee, link);
6767 const auto tx = get_transaction (link, false );
6868 if (!tx || tx->is_coinbase () || !populate_without_metadata (*tx))
6969 return false ;
7070
7171 out.bytes = tx->virtual_size ();
7272 out.fee = tx->fee ();
7373 return true ;
74- #else
75- table::transaction::get_coinbase tx{};
76- if (!store_.tx .get (link, tx) || tx.coinbase )
77- return false ;
78-
79- return get_tx_virtual_size (out.bytes , link) && get_tx_fee (out.fee , link);
80- #endif // SLOW_FEES
8174}
82-
75+
8376TEMPLATE
8477bool CLASS::get_block_fees (fee_rates& out,
8578 const header_link& link) const NOEXCEPT
8679{
87- #if defined(SLOW_FEES)
88- out.clear ();
89- const auto block = get_block (link, false );
90- if (!block)
91- return false ;
92-
93- block->populate ();
94- if (!populate_without_metadata (*block))
95- return false ;
96-
97- const auto & txs = *block->transactions_ptr ();
98- if (txs.empty ())
99- return false ;
100-
101- out.reserve (txs.size ());
102- for (auto tx = std::next (txs.begin ()); tx != txs.end (); ++tx)
103- out.emplace_back ((*tx)->virtual_size (), (*tx)->fee ());
104-
105- return true ;
106- #else // FAST_FEES|FASTER_FEES
10780 out.clear ();
10881 table::txs::get_txs txs{};
10982 if (!store_.txs .at (to_txs (link), txs) || (txs.tx_fks .size () < one))
11083 return false ;
11184
112- std::atomic_bool fail{};
11385 out.resize (sub1 (txs.tx_fks .size ()));
114- const auto begin = std::next (txs.tx_fks .begin ());
115- constexpr auto parallel = poolstl::execution::par;
116- constexpr auto relaxed = std::memory_order_relaxed;
86+ const auto end = txs.tx_fks .end ();
87+ auto rate = out.begin ();
11788
118- std::transform (parallel, begin, txs.tx_fks .end (), out.begin (),
119- [&](const auto & tx_fk) NOEXCEPT
120- {
121- fee_rate rate{};
122- if (!fail.load (relaxed) && !get_tx_fees (rate, tx_fk))
123- fail.store (true , relaxed);
124-
125- return rate;
126- });
89+ // Skip coinbase.
90+ for (auto tx = std::next (txs.tx_fks .begin ()); tx != end; ++tx)
91+ if (!get_tx_fees (*rate++, *tx))
92+ return false ;
12793
128- return !fail.load (relaxed);
129- #endif // SLOW_FEES
94+ return true ;
13095}
13196
13297TEMPLATE
@@ -137,20 +102,19 @@ bool CLASS::get_branch_fees(std::atomic_bool& cancel, fee_rate_sets& out,
137102 if (is_zero (count))
138103 return true ;
139104
140- if (system::is_add_overflow (start, sub1 (count)))
141- return false ;
142-
143- const auto last = start + sub1 (count);
144- if (last > get_top_confirmed ())
105+ if (system::is_add_overflow (start, sub1 (count)) ||
106+ (start + sub1 (count) > get_top_confirmed ()))
145107 return false ;
146108
147109 out.resize (count);
110+ std::atomic_bool fail{};
148111 std::vector<size_t > offsets (count);
149112 std::iota (offsets.begin (), offsets.end (), zero);
150-
151- std::atomic_bool fail{};
113+ constexpr auto parallel = poolstl::execution::par;
152114 constexpr auto relaxed = std::memory_order_relaxed;
153- std::for_each (poolstl::execution::par, offsets.begin (), offsets.end (),
115+
116+ // Parallel execution saves ~50%.
117+ std::for_each (parallel, offsets.begin (), offsets.end (),
154118 [&](const size_t & offset) NOEXCEPT
155119 {
156120 if (fail.load (relaxed))
0 commit comments