Skip to content

Commit ee9545f

Browse files
committed
Integrate turbo setting and use in address queries.
1 parent 1e5c96d commit ee9545f

File tree

8 files changed

+268
-12
lines changed

8 files changed

+268
-12
lines changed

include/bitcoin/database/impl/query/optional.ipp

Lines changed: 140 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,85 @@ namespace database {
3333

3434
// Address (natural-keyed).
3535
// ----------------------------------------------------------------------------
36-
// Pushing into vectors is more efficient than precomputation of size.
3736

37+
// private/static
3838
TEMPLATE
39-
code CLASS::get_address_outputs(const std::atomic_bool& cancel,
39+
template <typename Functor>
40+
inline code CLASS::parallel_address_transform(const std::atomic_bool& cancel,
41+
outpoints& out, const output_links& links, Functor&& functor) NOEXCEPT
42+
{
43+
constexpr auto parallel = poolstl::execution::par;
44+
45+
std::atomic_bool fail{};
46+
std::vector<outpoint> outpoints(links.size());
47+
std::transform(parallel, links.begin(), links.end(), outpoints.begin(),
48+
[&functor, &fail](const auto& link) NOEXCEPT
49+
{
50+
return functor(link, fail);
51+
});
52+
53+
out.clear();
54+
if (fail) return error::integrity;
55+
if (cancel) return error::canceled;
56+
for (auto& outpoint: outpoints)
57+
{
58+
if (cancel) return error::canceled;
59+
if (outpoint.point().index() != point::null_index)
60+
out.insert(std::move(outpoint));
61+
}
62+
63+
return error::success;
64+
}
65+
66+
// protected
67+
TEMPLATE
68+
code CLASS::to_address_outputs(const std::atomic_bool& cancel,
69+
output_links& out, const hash_digest& key) const NOEXCEPT
70+
{
71+
// Pushing into the vector is more efficient than precomputation of size.
72+
out.clear();
73+
for (auto it = store_.address.it(key); it; ++it)
74+
{
75+
if (cancel)
76+
return error::canceled;
77+
78+
table::address::record address{};
79+
if (!store_.address.get(it, address))
80+
return error::integrity;
81+
82+
out.push_back(address.output_fk);
83+
}
84+
85+
return error::success;
86+
}
87+
88+
// protected
89+
TEMPLATE
90+
code CLASS::get_address_outputs_turbo(const std::atomic_bool& cancel,
4091
outpoints& out, const hash_digest& key) const NOEXCEPT
4192
{
93+
out.clear();
94+
output_links links{};
95+
if (const code ec = to_address_outputs(cancel, links, key))
96+
return ec;
97+
98+
return parallel_address_transform(cancel, out, links,
99+
[this, &cancel](const auto& link, auto& fail) NOEXCEPT
100+
{
101+
if (cancel || fail) return outpoint{};
102+
auto outpoint = get_spent(link);
103+
fail = (outpoint.point().index() == point::null_index);
104+
return outpoint;
105+
});
106+
}
107+
108+
TEMPLATE
109+
code CLASS::get_address_outputs(const std::atomic_bool& cancel,
110+
outpoints& out, const hash_digest& key, bool turbo) const NOEXCEPT
111+
{
112+
if (turbo && store_.turbo())
113+
return get_address_outputs_turbo(cancel, out, key);
114+
42115
out.clear();
43116
for (auto it = store_.address.it(key); it; ++it)
44117
{
@@ -55,10 +128,35 @@ code CLASS::get_address_outputs(const std::atomic_bool& cancel,
55128
return error::success;
56129
}
57130

131+
// protected
58132
TEMPLATE
59-
code CLASS::get_confirmed_unspent_outputs(const std::atomic_bool& cancel,
133+
code CLASS::get_confirmed_unspent_outputs_turbo(const std::atomic_bool& cancel,
60134
outpoints& out, const hash_digest& key) const NOEXCEPT
61135
{
136+
out.clear();
137+
output_links links{};
138+
if (const code ec = to_address_outputs(cancel, links, key))
139+
return ec;
140+
141+
return parallel_address_transform(cancel, out, links,
142+
[this, &cancel](const auto& link, auto& fail) NOEXCEPT
143+
{
144+
if (cancel || fail || !is_confirmed_unspent(link))
145+
return outpoint{};
146+
147+
auto outpoint = get_spent(link);
148+
fail = (outpoint.point().index() == point::null_index);
149+
return outpoint;
150+
});
151+
}
152+
153+
TEMPLATE
154+
code CLASS::get_confirmed_unspent_outputs(const std::atomic_bool& cancel,
155+
outpoints& out, const hash_digest& key, bool turbo) const NOEXCEPT
156+
{
157+
if (turbo && store_.turbo())
158+
return get_confirmed_unspent_outputs_turbo(cancel, out, key);
159+
62160
out.clear();
63161
for (auto it = store_.address.it(key); it; ++it)
64162
{
@@ -76,10 +174,46 @@ code CLASS::get_confirmed_unspent_outputs(const std::atomic_bool& cancel,
76174
return error::success;
77175
}
78176

177+
// protected
79178
TEMPLATE
80-
code CLASS::get_minimum_unspent_outputs(const std::atomic_bool& cancel,
179+
code CLASS::get_minimum_unspent_outputs_turbo(const std::atomic_bool& cancel,
81180
outpoints& out, const hash_digest& key, uint64_t minimum) const NOEXCEPT
82181
{
182+
out.clear();
183+
output_links links{};
184+
if (const code ec = to_address_outputs(cancel, links, key))
185+
return ec;
186+
187+
return parallel_address_transform(cancel, out, links,
188+
[this, &cancel, minimum](const auto& link, auto& fail) NOEXCEPT
189+
{
190+
if (cancel || fail || !is_confirmed_unspent(link))
191+
return outpoint{};
192+
193+
uint64_t value{};
194+
if (!get_value(value, link))
195+
{
196+
fail = true;
197+
return outpoint{};
198+
}
199+
200+
if (value < minimum)
201+
return outpoint{};
202+
203+
auto outpoint = get_spent(link);
204+
fail = (outpoint.point().index() == point::null_index);
205+
return outpoint;
206+
});
207+
}
208+
209+
TEMPLATE
210+
code CLASS::get_minimum_unspent_outputs(const std::atomic_bool& cancel,
211+
outpoints& out, const hash_digest& key,
212+
uint64_t minimum, bool turbo) const NOEXCEPT
213+
{
214+
if (turbo && store_.turbo())
215+
return get_minimum_unspent_outputs_turbo(cancel, out, key, minimum);
216+
83217
out.clear();
84218
for (auto it = store_.address.it(key); it; ++it)
85219
{
@@ -106,10 +240,10 @@ code CLASS::get_minimum_unspent_outputs(const std::atomic_bool& cancel,
106240

107241
TEMPLATE
108242
code CLASS::get_confirmed_balance(const std::atomic_bool& cancel,
109-
uint64_t& balance, const hash_digest& key) const NOEXCEPT
243+
uint64_t& balance, const hash_digest& key, bool turbo) const NOEXCEPT
110244
{
111245
outpoints outs{};
112-
if (code ec = get_confirmed_unspent_outputs(cancel, outs, key))
246+
if (code ec = get_confirmed_unspent_outputs(cancel, outs, key, turbo))
113247
{
114248
balance = zero;
115249
return ec;

include/bitcoin/database/impl/store.ipp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ CLASS::store(const settings& config) NOEXCEPT
225225
{
226226
}
227227

228+
TEMPLATE
229+
bool CLASS::turbo() const NOEXCEPT
230+
{
231+
return configuration_.turbo;
232+
}
233+
228234
TEMPLATE
229235
code CLASS::create(const event_handler& handler) NOEXCEPT
230236
{

include/bitcoin/database/query.hpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ class query
313313
point_link top_point(size_t bucket) const NOEXCEPT;
314314
tx_link top_tx(size_t bucket) const NOEXCEPT;
315315

316+
/// optional enumeration
317+
code to_address_outputs(const std::atomic_bool& cancel,
318+
output_links& out, const hash_digest& key) const NOEXCEPT;
319+
316320
/// Archive reads.
317321
/// -----------------------------------------------------------------------
318322

@@ -550,13 +554,14 @@ class query
550554
/// -----------------------------------------------------------------------
551555

552556
code get_address_outputs(const std::atomic_bool& cancel,
553-
outpoints& out, const hash_digest& key) const NOEXCEPT;
557+
outpoints& out, const hash_digest& key, bool turbo=false) const NOEXCEPT;
554558
code get_confirmed_unspent_outputs(const std::atomic_bool& cancel,
555-
outpoints& out, const hash_digest& key) const NOEXCEPT;
559+
outpoints& out, const hash_digest& key, bool turbo=false) const NOEXCEPT;
556560
code get_minimum_unspent_outputs(const std::atomic_bool& cancel,
557-
outpoints& out, const hash_digest& key, uint64_t value) const NOEXCEPT;
561+
outpoints& out, const hash_digest& key, uint64_t value,
562+
bool turbo=false) const NOEXCEPT;
558563
code get_confirmed_balance(const std::atomic_bool& cancel,
559-
uint64_t& balance, const hash_digest& key) const NOEXCEPT;
564+
uint64_t& balance, const hash_digest& key, bool turbo=false) const NOEXCEPT;
560565

561566
bool is_filtered_body(const header_link& link) const NOEXCEPT;
562567
bool get_filter_body(filter& out, const header_link& link) const NOEXCEPT;
@@ -687,6 +692,16 @@ class query
687692
const system::settings& settings, const header& header,
688693
const header_link& link, size_t height) const NOEXCEPT;
689694

695+
/// address
696+
/// -----------------------------------------------------------------------
697+
698+
code get_address_outputs_turbo(const std::atomic_bool& cancel,
699+
outpoints& out, const hash_digest& key) const NOEXCEPT;
700+
code get_confirmed_unspent_outputs_turbo(const std::atomic_bool& cancel,
701+
outpoints& out, const hash_digest& key) const NOEXCEPT;
702+
code get_minimum_unspent_outputs_turbo(const std::atomic_bool& cancel,
703+
outpoints& out, const hash_digest& key, uint64_t minimum) const NOEXCEPT;
704+
690705
/// tx_fk must be allocated.
691706
/// -----------------------------------------------------------------------
692707
code set_code(const tx_link& tx_fk, const transaction& tx) NOEXCEPT;
@@ -696,6 +711,10 @@ class query
696711
template <typename Bool>
697712
static inline bool push_bool(std_vector<Bool>& stack,
698713
const Bool& element) NOEXCEPT;
714+
template <typename Functor>
715+
static inline code parallel_address_transform(
716+
const std::atomic_bool& cancel, outpoints& out,
717+
const output_links& links, Functor&& functor) NOEXCEPT;
699718

700719
// Not thread safe.
701720
size_t get_fork_() const NOEXCEPT;

include/bitcoin/database/settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct BCD_API settings
3737
settings(system::chain::selection context) NOEXCEPT;
3838

3939
/// Properties.
40+
bool turbo;
4041
std::filesystem::path path;
4142

4243
/// Archives.

include/bitcoin/database/store.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ class store
5454
/// Construct a store from settings.
5555
store(const settings& config) NOEXCEPT;
5656

57+
/// Properties
58+
/// -----------------------------------------------------------------------
59+
60+
/// Allow full throttle concurrent query execution (may use 100% CPU).
61+
bool turbo() const NOEXCEPT;
62+
5763
/// Methods.
5864
/// -----------------------------------------------------------------------
5965

src/settings.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ namespace database {
2727
using namespace bc::system;
2828

2929
settings::settings() NOEXCEPT
30-
: path{ "bitcoin" },
30+
: turbo{ false },
31+
path{ "bitcoin" },
3132

3233
// Archives.
3334

0 commit comments

Comments
 (0)