mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Move SHAMap hash computations from dirtyUp to walkSubTree
in order to reduce the total number of hash computations.
This commit is contained in:
committed by
Tom Ritchford
parent
0083c32629
commit
698fe73608
@@ -269,13 +269,6 @@ SHAMap::setLedgerSeq (std::uint32_t lseq)
|
||||
ledgerSeq_ = lseq;
|
||||
}
|
||||
|
||||
inline
|
||||
uint256
|
||||
SHAMap::getHash () const
|
||||
{
|
||||
return root_->getNodeHash ();
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
SHAMap::setImmutable ()
|
||||
|
||||
@@ -77,8 +77,7 @@ public:
|
||||
uint256 const& getNodeHash () const;
|
||||
|
||||
public: // public only to SHAMap
|
||||
bool setChild (int m, uint256 const& hash,
|
||||
std::shared_ptr<SHAMapTreeNode> const& child);
|
||||
void setChild (int m, std::shared_ptr<SHAMapTreeNode> const& child);
|
||||
void shareChild (int m, std::shared_ptr<SHAMapTreeNode> const& child);
|
||||
|
||||
// node functions
|
||||
@@ -118,12 +117,13 @@ public: // public only to SHAMap
|
||||
void dump (SHAMapNodeID const&, beast::Journal journal);
|
||||
#endif
|
||||
std::string getString (SHAMapNodeID const&) const;
|
||||
bool updateHash ();
|
||||
void updateHashDeep();
|
||||
|
||||
private:
|
||||
bool isTransaction () const;
|
||||
bool hasMetaData () const;
|
||||
bool isAccountState () const;
|
||||
bool updateHash ();
|
||||
};
|
||||
|
||||
inline
|
||||
|
||||
@@ -137,14 +137,7 @@ SHAMap::dirtyUp (SharedPtrNodeStack& stack,
|
||||
assert (branch >= 0);
|
||||
|
||||
unshareNode (node, nodeID);
|
||||
|
||||
if (! node->setChild (branch, child->getNodeHash(), child))
|
||||
{
|
||||
journal_.fatal <<
|
||||
"dirtyUp terminates early";
|
||||
assert (false);
|
||||
return;
|
||||
}
|
||||
node->setChild (branch, child);
|
||||
|
||||
#ifdef ST_DEBUG
|
||||
if (journal_.trace) journal_.trace <<
|
||||
@@ -701,11 +694,7 @@ bool SHAMap::delItem (uint256 const& id)
|
||||
assert (node->isInner ());
|
||||
|
||||
unshareNode (node, nodeID);
|
||||
if (! node->setChild (nodeID.selectBranch (id), prevHash, prevNode))
|
||||
{
|
||||
assert (false);
|
||||
return true;
|
||||
}
|
||||
node->setChild (nodeID.selectBranch (id), prevNode);
|
||||
|
||||
if (!nodeID.isRoot ())
|
||||
{
|
||||
@@ -730,10 +719,7 @@ bool SHAMap::delItem (uint256 const& id)
|
||||
{
|
||||
if (!node->isEmptyBranch (i))
|
||||
{
|
||||
if (! node->setChild (i, uint256(), nullptr))
|
||||
{
|
||||
assert (false);
|
||||
}
|
||||
node->setChild (i, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -742,14 +728,12 @@ bool SHAMap::delItem (uint256 const& id)
|
||||
|
||||
prevHash = node->getNodeHash ();
|
||||
prevNode = std::move (node);
|
||||
assert (prevHash.isNonZero ());
|
||||
}
|
||||
else
|
||||
{
|
||||
// This node is now the end of the branch
|
||||
prevHash = node->getNodeHash ();
|
||||
prevNode = std::move (node);
|
||||
assert (prevHash.isNonZero ());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -787,10 +771,7 @@ SHAMap::addGiveItem (std::shared_ptr<SHAMapItem> const& item,
|
||||
int branch = nodeID.selectBranch (tag);
|
||||
assert (node->isEmptyBranch (branch));
|
||||
auto newNode = std::make_shared<SHAMapTreeNode> (item, type, seq_);
|
||||
if (! node->setChild (branch, newNode->getNodeHash (), newNode))
|
||||
{
|
||||
assert (false);
|
||||
}
|
||||
node->setChild (branch, newNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -819,17 +800,11 @@ SHAMap::addGiveItem (std::shared_ptr<SHAMapItem> const& item,
|
||||
std::shared_ptr<SHAMapTreeNode> newNode =
|
||||
std::make_shared<SHAMapTreeNode> (item, type, seq_);
|
||||
assert (newNode->isValid () && newNode->isLeaf ());
|
||||
if (!node->setChild (b1, newNode->getNodeHash (), newNode))
|
||||
{
|
||||
assert (false);
|
||||
}
|
||||
node->setChild (b1, newNode);
|
||||
|
||||
newNode = std::make_shared<SHAMapTreeNode> (otherItem, type, seq_);
|
||||
assert (newNode->isValid () && newNode->isLeaf ());
|
||||
if (!node->setChild (b2, newNode->getNodeHash (), newNode))
|
||||
{
|
||||
assert (false);
|
||||
}
|
||||
node->setChild (b2, newNode);
|
||||
}
|
||||
|
||||
dirtyUp (stack, tag, node);
|
||||
@@ -841,6 +816,18 @@ bool SHAMap::addItem (const SHAMapItem& i, bool isTransaction, bool hasMetaData)
|
||||
return addGiveItem (std::make_shared<SHAMapItem> (i), isTransaction, hasMetaData);
|
||||
}
|
||||
|
||||
uint256
|
||||
SHAMap::getHash () const
|
||||
{
|
||||
auto hash = root_->getNodeHash();
|
||||
if (hash.isZero())
|
||||
{
|
||||
const_cast<SHAMap&>(*this).unshare();
|
||||
hash = root_->getNodeHash();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool
|
||||
SHAMap::updateGiveItem (std::shared_ptr<SHAMapItem> const& item,
|
||||
bool isTransaction, bool hasMeta)
|
||||
@@ -1034,6 +1021,7 @@ SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
|
||||
preFlushNode (child);
|
||||
|
||||
assert (node->getSeq() == seq_);
|
||||
child->updateHash();
|
||||
|
||||
if (doWrite && backed_)
|
||||
writeNode (t, seq, child);
|
||||
@@ -1044,6 +1032,9 @@ SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
|
||||
}
|
||||
}
|
||||
|
||||
// update the hash of this inner node
|
||||
node->updateHashDeep();
|
||||
|
||||
// This inner node can now be shared
|
||||
if (doWrite && backed_)
|
||||
writeNode (t, seq, node);
|
||||
|
||||
@@ -310,6 +310,17 @@ bool SHAMapTreeNode::updateHash ()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SHAMapTreeNode::updateHashDeep()
|
||||
{
|
||||
for (auto pos = 0; pos < 16; ++pos)
|
||||
{
|
||||
if (mChildren[pos] != nullptr)
|
||||
mHashes[pos] = mChildren[pos]->mHash;
|
||||
}
|
||||
updateHash();
|
||||
}
|
||||
|
||||
void SHAMapTreeNode::addRaw (Serializer& s, SHANodeFormat format)
|
||||
{
|
||||
assert ((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH));
|
||||
@@ -490,32 +501,20 @@ std::string SHAMapTreeNode::getString (const SHAMapNodeID & id) const
|
||||
}
|
||||
|
||||
// We are modifying an inner node
|
||||
bool SHAMapTreeNode::setChild (int m, uint256 const& hash, std::shared_ptr<SHAMapTreeNode> const& child)
|
||||
void
|
||||
SHAMapTreeNode::setChild (int m, std::shared_ptr<SHAMapTreeNode> const& child)
|
||||
{
|
||||
assert ((m >= 0) && (m < 16));
|
||||
assert (mType == tnINNER);
|
||||
assert (mSeq != 0);
|
||||
assert (child.get() != this);
|
||||
|
||||
if (mHashes[m] == hash)
|
||||
return false;
|
||||
|
||||
mHashes[m] = hash;
|
||||
|
||||
if (hash.isNonZero ())
|
||||
{
|
||||
assert (child && (child->getNodeHash() == hash));
|
||||
mHashes[m].zero();
|
||||
mHash.zero();
|
||||
if (child)
|
||||
mIsBranch |= (1 << m);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (!child);
|
||||
mIsBranch &= ~ (1 << m);
|
||||
}
|
||||
|
||||
mChildren[m] = child;
|
||||
|
||||
return updateHash ();
|
||||
}
|
||||
|
||||
// finished modifying, now make shareable
|
||||
@@ -526,7 +525,6 @@ void SHAMapTreeNode::shareChild (int m, std::shared_ptr<SHAMapTreeNode> const& c
|
||||
assert (mSeq != 0);
|
||||
assert (child);
|
||||
assert (child.get() != this);
|
||||
assert (child->getNodeHash() == mHashes[m]);
|
||||
|
||||
mChildren[m] = child;
|
||||
}
|
||||
@@ -546,7 +544,6 @@ std::shared_ptr<SHAMapTreeNode> SHAMapTreeNode::getChild (int branch)
|
||||
assert (isInnerNode ());
|
||||
|
||||
std::unique_lock <std::mutex> lock (childLock);
|
||||
assert (!mChildren[branch] || (mHashes[branch] == mChildren[branch]->getNodeHash()));
|
||||
return mChildren[branch];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user