Skip to content

Commit c66829c

Browse files
committed
Change prevout table to slab.
1 parent 0814df9 commit c66829c

3 files changed

Lines changed: 31 additions & 30 deletions

File tree

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -301,16 +301,16 @@ error::error_t CLASS::unspendable(uint32_t sequence, bool coinbase,
301301
return error::unconfirmed_spend;
302302
}
303303

304-
const auto bip68 = ctx.is_enabled(system::chain::flags::bip68_rule) &&
305-
(version >= system::chain::relative_locktime_min_version);
304+
const auto relative = ctx.is_enabled(system::chain::flags::bip68_rule) &&
305+
transaction::is_relative_locktime_applied(coinbase, version, sequence);
306306

307-
if (bip68 || coinbase)
307+
if (relative || coinbase)
308308
{
309309
context out{};
310310
if (!get_context(out, strong))
311311
return error::integrity7;
312312

313-
if (bip68 &&
313+
if (relative &&
314314
input::is_locked(sequence, ctx.height, ctx.mtp, out.height, out.mtp))
315315
return error::relative_time_locked;
316316

@@ -333,7 +333,7 @@ code CLASS::populate_prevouts(point_sets& sets, size_t points,
333333
if (sets.empty())
334334
return error::success;
335335

336-
table::prevout::record_get cache{};
336+
table::prevout::slab_get cache{};
337337
cache.spends.resize(points);
338338
if (!store_.prevout.at(link, cache))
339339
return error::integrity8;
@@ -347,8 +347,8 @@ code CLASS::populate_prevouts(point_sets& sets, size_t points,
347347
for (auto& point: set.points)
348348
{
349349
const auto& pair = *it++;
350-
point.tx = table::prevout::record_get::output_tx_fk(pair.first);
351-
point.coinbase = table::prevout::record_get::coinbase(pair.first);
350+
point.tx = table::prevout::slab_get::output_tx_fk(pair.first);
351+
point.coinbase = table::prevout::slab_get::coinbase(pair.first);
352352
point.sequence = pair.second;
353353
}
354354

@@ -489,7 +489,7 @@ code CLASS::set_prevouts(const header_link& link, const block& block) NOEXCEPT
489489
const auto scope = store_.get_transactor();
490490

491491
// Clean single allocation failure (e.g. disk full).
492-
const table::prevout::record_put_ref prevouts{ {}, spenders, block };
492+
const table::prevout::slab_put_ref prevouts{ {}, spenders, block };
493493
return store_.prevout.put(link, prevouts) ? error::success :
494494
error::integrity11;
495495
// ========================================================================

include/bitcoin/database/tables/caches/prevout.hpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace table {
3131

3232
/// prevout is an array map index of previous outputs by block link.
3333
/// The coinbase flag is merged into the tx field, reducing it's domain.
34-
/// Masking is from the right in order to accomodate non-integral domain.
34+
/// Masking is from the right in order to accomodate integral tx domain.
3535
struct prevout
3636
: public array_map<schema::prevout>
3737
{
@@ -44,12 +44,12 @@ struct prevout
4444
static_assert(tx::size == sizeof(uint32_t), "sequence-tx overload error");
4545

4646
// This supports only a single record (not too useful).
47-
struct record
47+
struct slab
4848
: public schema::prevout
4949
{
5050
inline link count() const NOEXCEPT
5151
{
52-
return one;
52+
return tx::size;
5353
}
5454

5555
inline bool coinbase() const NOEXCEPT
@@ -83,7 +83,7 @@ struct prevout
8383
return sink;
8484
}
8585

86-
inline bool operator==(const record& other) const NOEXCEPT
86+
inline bool operator==(const slab& other) const NOEXCEPT
8787
{
8888
return coinbase() == other.coinbase()
8989
&& output_tx_fk() == other.output_tx_fk();
@@ -92,15 +92,16 @@ struct prevout
9292
tx::integer prevout_tx{};
9393
};
9494

95-
struct record_put_ref
95+
struct slab_put_ref
9696
: public schema::prevout
9797
{
9898
inline link count() const NOEXCEPT
9999
{
100100
// TODO: assert overflow.
101101
using namespace system;
102-
return add1(possible_narrow_cast<tx::integer>(conflicts.size())) +
103-
two * possible_narrow_cast<tx::integer>(block.spends());
102+
const auto conflicts_ = conflicts.size();
103+
return variable_size(conflicts_) + (conflicts_ * tx::size) +
104+
(block.spends() * (tx::size + sizeof(uint32_t)));
104105
}
105106

106107
static constexpr tx::integer merge(bool coinbase,
@@ -140,7 +141,7 @@ struct prevout
140141
BC_ASSERT_MSG(txs.size() > one, "empty block");
141142

142143
// Count is written as a tx link so the table can remain an array.
143-
sink.write_little_endian<tx::integer, tx::size>(number);
144+
sink.write_variable(number);
144145
std::for_each(cons.begin(), cons.end(), write_con);
145146
std::for_each(std::next(txs.begin()), txs.end(), write_tx);
146147

@@ -152,21 +153,22 @@ struct prevout
152153
const system::chain::block& block{};
153154
};
154155

155-
struct record_get
156+
struct slab_get
156157
: public schema::prevout
157158
{
158159
inline link count() const NOEXCEPT
159160
{
160161
// TODO: assert overflow.
161162
using namespace system;
162-
return possible_narrow_cast<tx::integer>(add1(conflicts.size())) +
163-
two * possible_narrow_cast<tx::integer>(spends.size());
163+
const auto conflicts_ = conflicts.size();
164+
return variable_size(conflicts_) + (conflicts_ * tx::size) +
165+
(spends.size() * (tx::size + sizeof(uint32_t)));
164166
}
165167

166168
inline bool from_data(reader& source) NOEXCEPT
167169
{
168170
auto& cons = conflicts;
169-
cons.resize(source.read_little_endian<tx::integer, tx::size>());
171+
cons.resize(source.read_variable());
170172
std::for_each(cons.begin(), cons.end(), [&](auto& value) NOEXCEPT
171173
{
172174
value = source.read_little_endian<tx::integer, tx::size>();

include/bitcoin/database/tables/schema.hpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ namespace schema
115115
constexpr size_t puts_ = 4; // ->puts record.
116116
constexpr size_t spend_ = 4; // ->spend record.
117117
constexpr size_t point_ = 4; // ->point record.
118+
constexpr size_t prevout_ = 5; // ->prevout slab.
118119
constexpr size_t txs_ = 5; // ->txs slab.
119120
constexpr size_t tx = 4; // ->tx record.
120121
constexpr size_t block = 3; // ->header record.
@@ -318,21 +319,19 @@ namespace schema
318319
/// Cache tables.
319320
/// -----------------------------------------------------------------------
320321

321-
// record arraymap
322+
// slab arraymap, one slab per block
322323
struct prevout
323324
{
324-
// Buckets are limited to header links, but links are based on the
325-
// number of spends plus conflicts. Conflicts are assumed to be zero
326-
// per block and conflict count is one (tx::pk) per non-empty block.
327-
static constexpr size_t pk = schema::point_;
325+
static constexpr size_t pk = schema::prevout_;
328326
static constexpr size_t minsize =
329327
////schema::bit + // merged bit into tx.
330-
schema::transaction::pk;
328+
one + // varint(conflict-count)
329+
schema::transaction::pk + // prevout_tx
330+
one; // varint(sequence)
331331
static constexpr size_t minrow = minsize;
332-
static constexpr size_t size = minsize;
333-
////static constexpr linkage<pk> count() NOEXCEPT { return 1; }
334-
static_assert(minsize == 4u);
335-
static_assert(minrow == 4u);
332+
static constexpr size_t size = max_size_t;
333+
static_assert(minsize == 6u);
334+
static_assert(minrow == 6u);
336335
};
337336

338337
// slab hashmap

0 commit comments

Comments
 (0)