mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Refactor and improve the SHAMap code:
This commit combines a number of cleanups, targeting both the code structure and the code logic. Large changes include: - Using more strongly-typed classes for SHAMap nodes, instead of relying on runtime-time detection of class types. This change saves 16 bytes of memory per node. - Improving the interface of SHAMap::addGiveItem and SHAMap::addItem to avoid the need for passing two bool arguments. - Documenting the "copy-on-write" semantics that SHAMap uses to efficiently track changes in individual nodes. - Removing unused code and simplifying several APIs. - Improving function naming.
This commit is contained in:
@@ -72,8 +72,8 @@ public:
|
||||
res->updateSkipList();
|
||||
|
||||
{
|
||||
res->stateMap().flushDirty(hotACCOUNT_NODE, res->info().seq);
|
||||
res->txMap().flushDirty(hotTRANSACTION_NODE, res->info().seq);
|
||||
res->stateMap().flushDirty(hotACCOUNT_NODE);
|
||||
res->txMap().flushDirty(hotTRANSACTION_NODE);
|
||||
}
|
||||
res->unshare();
|
||||
|
||||
|
||||
@@ -283,15 +283,14 @@ class DatabaseShard_test : public TestBase
|
||||
}
|
||||
|
||||
// Store the state map
|
||||
auto visitAcc = [&](SHAMapAbstractNode& node) {
|
||||
auto visitAcc = [&](SHAMapTreeNode const& node) {
|
||||
Serializer s;
|
||||
node.serializeWithPrefix(s);
|
||||
db.store(
|
||||
node.getType() == SHAMapAbstractNode::TNType::tnINNER
|
||||
? hotUNKNOWN
|
||||
: hotACCOUNT_NODE,
|
||||
node.getType() == SHAMapNodeType::tnINNER ? hotUNKNOWN
|
||||
: hotACCOUNT_NODE,
|
||||
std::move(s.modData()),
|
||||
node.getNodeHash().as_uint256(),
|
||||
node.getHash().as_uint256(),
|
||||
ledger.info().seq);
|
||||
return true;
|
||||
};
|
||||
@@ -311,15 +310,14 @@ class DatabaseShard_test : public TestBase
|
||||
}
|
||||
|
||||
// Store the transaction map
|
||||
auto visitTx = [&](SHAMapAbstractNode& node) {
|
||||
auto visitTx = [&](SHAMapTreeNode& node) {
|
||||
Serializer s;
|
||||
node.serializeWithPrefix(s);
|
||||
db.store(
|
||||
node.getType() == SHAMapAbstractNode::TNType::tnINNER
|
||||
? hotUNKNOWN
|
||||
: hotTRANSACTION_NODE,
|
||||
node.getType() == SHAMapNodeType::tnINNER ? hotUNKNOWN
|
||||
: hotTRANSACTION_NODE,
|
||||
std::move(s.modData()),
|
||||
node.getNodeHash().as_uint256(),
|
||||
node.getHash().as_uint256(),
|
||||
ledger.info().seq);
|
||||
return true;
|
||||
};
|
||||
@@ -357,20 +355,19 @@ class DatabaseShard_test : public TestBase
|
||||
LedgerFill{*fetched, LedgerFill::full | LedgerFill::binary}));
|
||||
|
||||
// walk shamap and validate each node
|
||||
auto fcompAcc = [&](SHAMapAbstractNode& node) -> bool {
|
||||
auto fcompAcc = [&](SHAMapTreeNode& node) -> bool {
|
||||
Serializer s;
|
||||
node.serializeWithPrefix(s);
|
||||
auto nSrc{NodeObject::createObject(
|
||||
node.getType() == SHAMapAbstractNode::TNType::tnINNER
|
||||
? hotUNKNOWN
|
||||
: hotACCOUNT_NODE,
|
||||
node.getType() == SHAMapNodeType::tnINNER ? hotUNKNOWN
|
||||
: hotACCOUNT_NODE,
|
||||
std::move(s.modData()),
|
||||
node.getNodeHash().as_uint256())};
|
||||
node.getHash().as_uint256())};
|
||||
if (!BEAST_EXPECT(nSrc))
|
||||
return false;
|
||||
|
||||
auto nDst = db.fetchNodeObject(
|
||||
node.getNodeHash().as_uint256(), ledger.info().seq);
|
||||
node.getHash().as_uint256(), ledger.info().seq);
|
||||
if (!BEAST_EXPECT(nDst))
|
||||
return false;
|
||||
|
||||
@@ -381,20 +378,19 @@ class DatabaseShard_test : public TestBase
|
||||
if (ledger.stateMap().getHash().isNonZero())
|
||||
ledger.stateMap().snapShot(false)->visitNodes(fcompAcc);
|
||||
|
||||
auto fcompTx = [&](SHAMapAbstractNode& node) -> bool {
|
||||
auto fcompTx = [&](SHAMapTreeNode& node) -> bool {
|
||||
Serializer s;
|
||||
node.serializeWithPrefix(s);
|
||||
auto nSrc{NodeObject::createObject(
|
||||
node.getType() == SHAMapAbstractNode::TNType::tnINNER
|
||||
? hotUNKNOWN
|
||||
: hotTRANSACTION_NODE,
|
||||
node.getType() == SHAMapNodeType::tnINNER ? hotUNKNOWN
|
||||
: hotTRANSACTION_NODE,
|
||||
std::move(s.modData()),
|
||||
node.getNodeHash().as_uint256())};
|
||||
node.getHash().as_uint256())};
|
||||
if (!BEAST_EXPECT(nSrc))
|
||||
return false;
|
||||
|
||||
auto nDst = db.fetchNodeObject(
|
||||
node.getNodeHash().as_uint256(), ledger.info().seq);
|
||||
node.getHash().as_uint256(), ledger.info().seq);
|
||||
if (!BEAST_EXPECT(nDst))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
SHAMapHash const& nodeHash,
|
||||
std::uint32_t ledgerSeq,
|
||||
Blob&& nodeData,
|
||||
SHAMapTreeNode::TNType type) const override
|
||||
SHAMapNodeType type) const override
|
||||
{
|
||||
}
|
||||
|
||||
@@ -100,7 +100,8 @@ public:
|
||||
while (n--)
|
||||
{
|
||||
std::shared_ptr<SHAMapItem> item(make_random_item(r));
|
||||
auto const result(t.addItem(std::move(*item), false, false));
|
||||
auto const result(
|
||||
t.addItem(SHAMapNodeType::tnACCOUNT_STATE, std::move(*item)));
|
||||
assert(result);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
std::shared_ptr<SHAMapItem> item = makeRandomAS();
|
||||
items.push_back(item->key());
|
||||
|
||||
if (!map.addItem(std::move(*item), false, false))
|
||||
if (!map.addItem(SHAMapNodeType::tnACCOUNT_STATE, std::move(*item)))
|
||||
{
|
||||
log << "Unable to add item to map\n";
|
||||
return false;
|
||||
@@ -98,7 +98,8 @@ public:
|
||||
int items = 10000;
|
||||
for (int i = 0; i < items; ++i)
|
||||
{
|
||||
source.addItem(std::move(*makeRandomAS()), false, false);
|
||||
source.addItem(
|
||||
SHAMapNodeType::tnACCOUNT_STATE, std::move(*makeRandomAS()));
|
||||
if (i % 100 == 0)
|
||||
source.invariants();
|
||||
}
|
||||
|
||||
@@ -64,12 +64,12 @@ static_assert(std::is_copy_assignable<SHAMapHash>{}, "");
|
||||
static_assert(std::is_move_constructible<SHAMapHash>{}, "");
|
||||
static_assert(std::is_move_assignable<SHAMapHash>{}, "");
|
||||
|
||||
static_assert(!std::is_nothrow_destructible<SHAMapAbstractNode>{}, "");
|
||||
static_assert(!std::is_default_constructible<SHAMapAbstractNode>{}, "");
|
||||
static_assert(!std::is_copy_constructible<SHAMapAbstractNode>{}, "");
|
||||
static_assert(!std::is_copy_assignable<SHAMapAbstractNode>{}, "");
|
||||
static_assert(!std::is_move_constructible<SHAMapAbstractNode>{}, "");
|
||||
static_assert(!std::is_move_assignable<SHAMapAbstractNode>{}, "");
|
||||
static_assert(std::is_nothrow_destructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_default_constructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_copy_constructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_copy_assignable<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_move_constructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_move_assignable<SHAMapTreeNode>{}, "");
|
||||
|
||||
static_assert(std::is_nothrow_destructible<SHAMapInnerNode>{}, "");
|
||||
static_assert(!std::is_default_constructible<SHAMapInnerNode>{}, "");
|
||||
@@ -78,12 +78,12 @@ static_assert(!std::is_copy_assignable<SHAMapInnerNode>{}, "");
|
||||
static_assert(!std::is_move_constructible<SHAMapInnerNode>{}, "");
|
||||
static_assert(!std::is_move_assignable<SHAMapInnerNode>{}, "");
|
||||
|
||||
static_assert(std::is_nothrow_destructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_default_constructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_copy_constructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_copy_assignable<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_move_constructible<SHAMapTreeNode>{}, "");
|
||||
static_assert(!std::is_move_assignable<SHAMapTreeNode>{}, "");
|
||||
static_assert(std::is_nothrow_destructible<SHAMapLeafNode>{}, "");
|
||||
static_assert(!std::is_default_constructible<SHAMapLeafNode>{}, "");
|
||||
static_assert(!std::is_copy_constructible<SHAMapLeafNode>{}, "");
|
||||
static_assert(!std::is_copy_assignable<SHAMapLeafNode>{}, "");
|
||||
static_assert(!std::is_move_constructible<SHAMapLeafNode>{}, "");
|
||||
static_assert(!std::is_move_assignable<SHAMapLeafNode>{}, "");
|
||||
#endif
|
||||
|
||||
inline bool
|
||||
@@ -161,9 +161,13 @@ public:
|
||||
|
||||
SHAMapItem i1(h1, IntToVUC(1)), i2(h2, IntToVUC(2)),
|
||||
i3(h3, IntToVUC(3)), i4(h4, IntToVUC(4)), i5(h5, IntToVUC(5));
|
||||
unexpected(!sMap.addItem(SHAMapItem{i2}, true, false), "no add");
|
||||
unexpected(
|
||||
!sMap.addItem(SHAMapNodeType::tnTRANSACTION_NM, SHAMapItem{i2}),
|
||||
"no add");
|
||||
sMap.invariants();
|
||||
unexpected(!sMap.addItem(SHAMapItem{i1}, true, false), "no add");
|
||||
unexpected(
|
||||
!sMap.addItem(SHAMapNodeType::tnTRANSACTION_NM, SHAMapItem{i1}),
|
||||
"no add");
|
||||
sMap.invariants();
|
||||
|
||||
auto i = sMap.begin();
|
||||
@@ -173,11 +177,11 @@ public:
|
||||
unexpected(i == e || (*i != i2), "bad traverse");
|
||||
++i;
|
||||
unexpected(i != e, "bad traverse");
|
||||
sMap.addItem(SHAMapItem{i4}, true, false);
|
||||
sMap.addItem(SHAMapNodeType::tnTRANSACTION_NM, SHAMapItem{i4});
|
||||
sMap.invariants();
|
||||
sMap.delItem(i2.key());
|
||||
sMap.invariants();
|
||||
sMap.addItem(SHAMapItem{i3}, true, false);
|
||||
sMap.addItem(SHAMapNodeType::tnTRANSACTION_NM, SHAMapItem{i3});
|
||||
sMap.invariants();
|
||||
i = sMap.begin();
|
||||
e = sMap.end();
|
||||
@@ -282,7 +286,8 @@ public:
|
||||
for (int k = 0; k < keys.size(); ++k)
|
||||
{
|
||||
SHAMapItem item(keys[k], IntToVUC(k));
|
||||
BEAST_EXPECT(map.addItem(std::move(item), true, false));
|
||||
BEAST_EXPECT(map.addItem(
|
||||
SHAMapNodeType::tnTRANSACTION_NM, std::move(item)));
|
||||
BEAST_EXPECT(map.getHash().as_uint256() == hashes[k]);
|
||||
map.invariants();
|
||||
}
|
||||
@@ -333,7 +338,9 @@ public:
|
||||
map.setUnbacked();
|
||||
for (auto const& k : keys)
|
||||
{
|
||||
map.addItem(SHAMapItem{k, IntToVUC(0)}, true, false);
|
||||
map.addItem(
|
||||
SHAMapNodeType::tnTRANSACTION_NM,
|
||||
SHAMapItem{k, IntToVUC(0)});
|
||||
map.invariants();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user