Skip to content

Commit c4cec94

Browse files
authored
Merge pull request #524 from evoskuil/master
Add put counts and block to put translations.
2 parents 87351a6 + c8e9207 commit c4cec94

File tree

5 files changed

+180
-70
lines changed

5 files changed

+180
-70
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ typename CLASS::inputs_ptr CLASS::get_inputs(
430430
{
431431
// TODO: eliminate shared memory pointer reallocations.
432432
using namespace system;
433-
const auto fks = to_tx_spends(link);
433+
const auto fks = to_spends(link);
434434
if (fks.empty())
435435
return {};
436436

@@ -450,7 +450,7 @@ typename CLASS::outputs_ptr CLASS::get_outputs(
450450
{
451451
// TODO: eliminate shared memory pointer reallocations.
452452
using namespace system;
453-
const auto fks = to_tx_outputs(link);
453+
const auto fks = to_outputs(link);
454454
if (fks.empty())
455455
return {};
456456

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef LIBBITCOIN_DATABASE_QUERY_EXTENT_IPP
2020
#define LIBBITCOIN_DATABASE_QUERY_EXTENT_IPP
2121

22+
#include <numeric>
2223
#include <bitcoin/system.hpp>
2324
#include <bitcoin/database/define.hpp>
2425

@@ -207,6 +208,26 @@ two_counts CLASS::put_counts(const tx_link& link) const NOEXCEPT
207208
return { tx.ins_count, tx.outs_count };
208209
}
209210

211+
TEMPLATE
212+
size_t CLASS::input_count(const tx_links& txs) const NOEXCEPT
213+
{
214+
const auto fn = [this](auto tx) NOEXCEPT { return input_count(tx); };
215+
return std_reduce(bc::par_unseq, txs.begin(), txs.end(), zero, fn);
216+
}
217+
218+
TEMPLATE
219+
size_t CLASS::output_count(const tx_links& txs) const NOEXCEPT
220+
{
221+
const auto fn = [this](auto tx) NOEXCEPT { return output_count(tx); };
222+
return std_reduce(bc::par_unseq, txs.begin(), txs.end(), zero, fn);
223+
}
224+
225+
TEMPLATE
226+
two_counts CLASS::put_counts(const tx_links& txs) const NOEXCEPT
227+
{
228+
return { input_count(txs), output_count(txs) };
229+
}
230+
210231
TEMPLATE
211232
bool CLASS::address_enabled() const NOEXCEPT
212233
{

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

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <algorithm>
2323
#include <iterator>
24+
#include <numeric>
2425
#include <unordered_map>
2526
#include <utility>
2627
#include <bitcoin/system.hpp>
@@ -326,7 +327,7 @@ uint32_t CLASS::to_spend_index(const tx_link& parent_fk,
326327
const spend_link& spend_fk) const NOEXCEPT
327328
{
328329
uint32_t index{};
329-
for (const auto& in_fk: to_tx_spends(parent_fk))
330+
for (const auto& in_fk: to_spends(parent_fk))
330331
{
331332
if (in_fk == spend_fk) return index;
332333
++index;
@@ -341,7 +342,7 @@ uint32_t CLASS::to_output_index(const tx_link& parent_fk,
341342
const output_link& output_fk) const NOEXCEPT
342343
{
343344
uint32_t index{};
344-
for (const auto& out_fk: to_tx_outputs(parent_fk))
345+
for (const auto& out_fk: to_outputs(parent_fk))
345346
{
346347
if (out_fk == output_fk) return index;
347348
++index;
@@ -356,7 +357,7 @@ spend_link CLASS::to_spender(const tx_link& link,
356357
const foreign_point& point) const NOEXCEPT
357358
{
358359
table::spend::get_key spend{};
359-
for (const auto& spend_fk: to_tx_spends(link))
360+
for (const auto& spend_fk: to_spends(link))
360361
if (store_.spend.get(spend_fk, spend) && (spend.key == point))
361362
return spend_fk;
362363

@@ -410,7 +411,7 @@ spend_links CLASS::to_spenders(const foreign_point& point) const NOEXCEPT
410411
return fault;
411412

412413
auto found{ false };
413-
for (const auto& spend_fk: to_tx_spends(spender.parent_fk))
414+
for (const auto& spend_fk: to_spends(spender.parent_fk))
414415
{
415416
table::spend::get_key spend{};
416417
if (!store_.spend.get(it, spend_fk, spend))
@@ -435,7 +436,22 @@ spend_links CLASS::to_spenders(const foreign_point& point) const NOEXCEPT
435436
// ----------------------------------------------------------------------------
436437

437438
TEMPLATE
438-
output_links CLASS::to_tx_outputs(const tx_link& link) const NOEXCEPT
439+
spend_links CLASS::to_spends(const tx_link& link) const NOEXCEPT
440+
{
441+
table::transaction::get_puts tx{};
442+
if (!store_.tx.get(link, tx))
443+
return {};
444+
445+
table::puts::get_spends puts{};
446+
puts.spend_fks.resize(tx.ins_count);
447+
if (!store_.puts.get(tx.puts_fk, puts))
448+
return {};
449+
450+
return std::move(puts.spend_fks);
451+
}
452+
453+
TEMPLATE
454+
output_links CLASS::to_outputs(const tx_link& link) const NOEXCEPT
439455
{
440456
table::transaction::get_puts tx{};
441457
if (!store_.tx.get(link, tx))
@@ -450,18 +466,18 @@ output_links CLASS::to_tx_outputs(const tx_link& link) const NOEXCEPT
450466
}
451467

452468
TEMPLATE
453-
spend_links CLASS::to_tx_spends(const tx_link& link) const NOEXCEPT
469+
output_links CLASS::to_prevouts(const tx_link& link) const NOEXCEPT
454470
{
455-
table::transaction::get_puts tx{};
456-
if (!store_.tx.get(link, tx))
471+
const auto spends = to_spends(link);
472+
if (spends.empty())
457473
return {};
458474

459-
table::puts::get_spends puts{};
460-
puts.spend_fks.resize(tx.ins_count);
461-
if (!store_.puts.get(tx.puts_fk, puts))
462-
return {};
475+
output_links prevouts{};
476+
prevouts.reserve(spends.size());
477+
for (const auto& spend: spends)
478+
prevouts.push_back(to_prevout(spend));
463479

464-
return std::move(puts.spend_fks);
480+
return prevouts;
465481
}
466482

467483
// protected
@@ -502,29 +518,71 @@ spend_set CLASS::to_spend_set(const tx_link& link) const NOEXCEPT
502518
return set;
503519
}
504520

505-
// block to txs/puts (forward navigation)
521+
// txs to puts (forward navigation)
506522
// ----------------------------------------------------------------------------
507523

508524
TEMPLATE
509-
tx_links CLASS::to_transactions(const header_link& link) const NOEXCEPT
525+
spend_links CLASS::to_spends(const tx_links& txs) const NOEXCEPT
510526
{
511-
table::txs::get_txs txs{};
512-
if (!store_.txs.find(link, txs))
513-
return {};
527+
spend_links spends{};
528+
for (const auto& tx: txs)
529+
{
530+
const auto tx_spends = to_spends(tx);
531+
spends.insert(spends.end(), tx_spends.begin(), tx_spends.end());
532+
}
514533

515-
return std::move(txs.tx_fks);
534+
return spends;
516535
}
517536

518537
TEMPLATE
519-
tx_links CLASS::to_spending_transactions(const header_link& link) const NOEXCEPT
538+
output_links CLASS::to_outputs(const tx_links& txs) const NOEXCEPT
520539
{
521-
table::txs::get_spending_txs txs{};
522-
if (!store_.txs.find(link, txs))
523-
return {};
540+
output_links outputs{};
541+
for (const auto& tx: txs)
542+
{
543+
const auto tx_outputs = to_outputs(tx);
544+
outputs.insert(outputs.end(), tx_outputs.begin(), tx_outputs.end());
545+
}
524546

525-
return std::move(txs.tx_fks);
547+
return outputs;
548+
}
549+
550+
TEMPLATE
551+
output_links CLASS::to_prevouts(const tx_links& txs) const NOEXCEPT
552+
{
553+
const auto ins = to_spends(txs);
554+
output_links outs(ins.size());
555+
const auto fn = [this](auto spend) NOEXCEPT{ return to_prevout(spend); };
556+
557+
// C++17 incomplete on GCC/CLang, so presently parallel only on MSVC++.
558+
std_transform(bc::par_unseq, ins.begin(), ins.end(), outs.begin(), fn);
559+
return outs;
560+
}
561+
562+
// block to puts (forward navigation)
563+
// ----------------------------------------------------------------------------
564+
565+
TEMPLATE
566+
spend_links CLASS::to_block_spends(const header_link& link) const NOEXCEPT
567+
{
568+
return to_spends(to_spending_transactions(link));
526569
}
527570

571+
TEMPLATE
572+
output_links CLASS::to_block_outputs(const header_link& link) const NOEXCEPT
573+
{
574+
return to_outputs(to_transactions(link));
575+
}
576+
577+
TEMPLATE
578+
output_links CLASS::to_block_prevouts(const header_link& link) const NOEXCEPT
579+
{
580+
return to_prevouts(to_spending_transactions(link));
581+
}
582+
583+
// block to txs (forward navigation)
584+
// ----------------------------------------------------------------------------
585+
528586
TEMPLATE
529587
tx_link CLASS::to_coinbase(const header_link& link) const NOEXCEPT
530588
{
@@ -536,33 +594,23 @@ tx_link CLASS::to_coinbase(const header_link& link) const NOEXCEPT
536594
}
537595

538596
TEMPLATE
539-
spend_links CLASS::to_block_spends(const header_link& link) const NOEXCEPT
597+
tx_links CLASS::to_transactions(const header_link& link) const NOEXCEPT
540598
{
541-
spend_links spends{};
542-
const auto txs = to_transactions(link);
543-
544-
for (const auto& tx: txs)
545-
{
546-
const auto tx_spends = to_tx_spends(tx);
547-
spends.insert(spends.end(), tx_spends.begin(), tx_spends.end());
548-
}
599+
table::txs::get_txs txs{};
600+
if (!store_.txs.find(link, txs))
601+
return {};
549602

550-
return spends;
603+
return std::move(txs.tx_fks);
551604
}
552605

553606
TEMPLATE
554-
output_links CLASS::to_block_outputs(const header_link& link) const NOEXCEPT
607+
tx_links CLASS::to_spending_transactions(const header_link& link) const NOEXCEPT
555608
{
556-
output_links outputs{};
557-
const auto txs = to_transactions(link);
558-
559-
for (const auto& tx: txs)
560-
{
561-
const auto tx_outputs = to_tx_outputs(tx);
562-
outputs.insert(outputs.end(), tx_outputs.begin(), tx_outputs.end());
563-
}
609+
table::txs::get_spending_txs txs{};
610+
if (!store_.txs.find(link, txs))
611+
return {};
564612

565-
return outputs;
613+
return std::move(txs.tx_fks);
566614
}
567615

568616
// hashmap enumeration

include/bitcoin/database/query.hpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ class query
217217
size_t input_count(const tx_link& link) const NOEXCEPT;
218218
size_t output_count(const tx_link& link) const NOEXCEPT;
219219
two_counts put_counts(const tx_link& link) const NOEXCEPT;
220+
size_t input_count(const tx_links& txs) const NOEXCEPT;
221+
size_t output_count(const tx_links& txs) const NOEXCEPT;
222+
two_counts put_counts(const tx_links& txs) const NOEXCEPT;
220223

221224
/// Optional table state.
222225
bool address_enabled() const NOEXCEPT;
@@ -270,7 +273,7 @@ class query
270273
uint32_t output_index) const NOEXCEPT;
271274
output_link to_prevout(const spend_link& link) const NOEXCEPT;
272275

273-
/// block/tx to block/s (reverse navigation)
276+
/// block/tx to block (reverse navigation)
274277
header_link to_parent(const header_link& link) const NOEXCEPT;
275278
header_link to_block(const tx_link& key) const NOEXCEPT;
276279

@@ -282,15 +285,24 @@ class query
282285
uint32_t output_index) const NOEXCEPT;
283286

284287
/// tx to puts (forward navigation)
285-
output_links to_tx_outputs(const tx_link& link) const NOEXCEPT;
286-
spend_links to_tx_spends(const tx_link& link) const NOEXCEPT;
288+
spend_links to_spends(const tx_link& link) const NOEXCEPT;
289+
output_links to_outputs(const tx_link& link) const NOEXCEPT;
290+
output_links to_prevouts(const tx_link& link) const NOEXCEPT;
287291

288-
/// block to txs/puts (forward navigation)
292+
/// txs to puts (forward navigation)
293+
spend_links to_spends(const tx_links& txs) const NOEXCEPT;
294+
output_links to_outputs(const tx_links& txs) const NOEXCEPT;
295+
output_links to_prevouts(const tx_links& txs) const NOEXCEPT;
296+
297+
/// block to puts (forward navigation)
298+
spend_links to_block_spends(const header_link& link) const NOEXCEPT;
299+
output_links to_block_outputs(const header_link& link) const NOEXCEPT;
300+
output_links to_block_prevouts(const header_link& link) const NOEXCEPT;
301+
302+
/// block to txs (forward navigation)
289303
tx_link to_coinbase(const header_link& link) const NOEXCEPT;
290304
tx_links to_transactions(const header_link& link) const NOEXCEPT;
291305
tx_links to_spending_transactions(const header_link& link) const NOEXCEPT;
292-
output_links to_block_outputs(const header_link& link) const NOEXCEPT;
293-
spend_links to_block_spends(const header_link& link) const NOEXCEPT;
294306

295307
/// hashmap enumeration
296308
header_link top_header(size_t bucket) const NOEXCEPT;

0 commit comments

Comments
 (0)