diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index 77f385bb49..35b8416cb1 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -282,10 +282,10 @@ SHAMapStoreImp::copyNode (std::uint64_t& nodeCount, if (! (++nodeCount % checkHealthInterval_)) { if (health()) - return true; + return false; } - return false; + return true; } void diff --git a/src/ripple/shamap/SHAMap.h b/src/ripple/shamap/SHAMap.h index 9bd49ffc83..51856b5334 100644 --- a/src/ripple/shamap/SHAMap.h +++ b/src/ripple/shamap/SHAMap.h @@ -177,10 +177,29 @@ public: // traverse functions const_iterator upper_bound(uint256 const& id) const; - void visitNodes (std::function const&) const; - void - visitLeaves( - std::function const&)> const&) const; + /** Visit every node in this SHAMap + + @param function called with every node visited. + If function returns false, visitNodes exits. + */ + void visitNodes (std::function const& function) const; + + /** Visit every node in this SHAMap that + is not present in the specified SHAMap + + @param function called with every node visited. + If function returns false, visitDifferences exits. + */ + void visitDifferences(SHAMap const* have, + std::function) const; + + /** Visit every leaf node in this SHAMap + + @param function called with every non inner node visited. + */ + void visitLeaves(std::function const&)> const&) const; // comparison/sync functions @@ -247,8 +266,6 @@ private: using DeltaRef = std::pair const&, std::shared_ptr const&>; - void visitDifferences(SHAMap const* have, std::function) const; - // tree node cache operations std::shared_ptr getCache (SHAMapHash const& hash) const; void canonicalize (SHAMapHash const& hash, std::shared_ptr&) const; diff --git a/src/ripple/shamap/impl/SHAMapSync.cpp b/src/ripple/shamap/impl/SHAMapSync.cpp index 53fc8f2eae..b06f12af2f 100644 --- a/src/ripple/shamap/impl/SHAMapSync.cpp +++ b/src/ripple/shamap/impl/SHAMapSync.cpp @@ -25,19 +25,21 @@ namespace ripple { void -SHAMap::visitLeaves( - std::function const& item)> const& leafFunction) const +SHAMap::visitLeaves(std::function const& item)> const& leafFunction) const { visitNodes( [&leafFunction](SHAMapAbstractNode& node) { - if (!node.isInner()) + if (! node.isInner()) leafFunction(static_cast(node).peekItem()); - return false; + return true; }); } -void SHAMap::visitNodes(std::function const& function) const +void +SHAMap::visitNodes(std::function const& function) const { // Visit every node in a SHAMap assert (root_->isValid ()); @@ -64,7 +66,7 @@ void SHAMap::visitNodes(std::function const& functio if (!node->isEmptyBranch (pos)) { std::shared_ptr child = descendNoStore (node, pos); - if (function (*child)) + if (! function (*child)) return; if (child->isLeaf ()) @@ -100,6 +102,74 @@ void SHAMap::visitNodes(std::function const& functio } } +void +SHAMap::visitDifferences(SHAMap const* have, + std::function function) const +{ + // Visit every node in this SHAMap that is not present + // in the specified SHAMap + assert (root_->isValid ()); + + if (! root_) + return; + + if (root_->getNodeHash ().isZero ()) + return; + + if (have && (root_->getNodeHash () == have->root_->getNodeHash ())) + return; + + if (root_->isLeaf ()) + { + auto leaf = std::static_pointer_cast(root_); + if (! have || ! have->hasLeafNode(leaf->peekItem()->key(), leaf->getNodeHash())) + function(*root_); + + return; + } + // contains unexplored non-matching inner node entries + using StackEntry = std::pair ; + std::stack > stack; + + stack.push ({static_cast(root_.get()), SHAMapNodeID{}}); + + while (! stack.empty()) + { + SHAMapInnerNode* node; + SHAMapNodeID nodeID; + std::tie (node, nodeID) = stack.top (); + stack.pop (); + + // 1) Add this node to the pack + if (! function(*node)) + return; + + // 2) push non-matching child inner nodes + for (int i = 0; i < 16; ++i) + { + if (! node->isEmptyBranch (i)) + { + auto const& childHash = node->getChildHash (i); + SHAMapNodeID childID = nodeID.getChildNodeID (i); + auto next = descendThrow(node, i); + + if (next->isInner ()) + { + if (! have || ! have->hasInnerNode(childID, childHash)) + stack.push ({static_cast(next), childID}); + } + else if (! have || ! have->hasLeafNode( + static_cast(next)->peekItem()->key(), + childHash)) + { + if (! function(*next)) + return; + } + } + } + } +} + // Starting at the position referred to by the specfied // StackEntry, process that node and its first resident // children, descending the SHAMap until we complete the @@ -753,68 +823,4 @@ void SHAMap::getFetchPack (SHAMap const* have, bool includeLeaves, int max, }); } -void -SHAMap::visitDifferences(SHAMap const* have, - std::function func) const -{ - // Visit every node in this SHAMap that is not present - // in the specified SHAMap - - if (root_->getNodeHash ().isZero ()) - return; - - if (have && (root_->getNodeHash () == have->root_->getNodeHash ())) - return; - - if (root_->isLeaf ()) - { - auto leaf = std::static_pointer_cast(root_); - if (!have || !have->hasLeafNode(leaf->peekItem()->key(), leaf->getNodeHash())) - func (*root_); - - return; - } - // contains unexplored non-matching inner node entries - using StackEntry = std::pair ; - std::stack > stack; - - stack.push ({static_cast(root_.get()), SHAMapNodeID{}}); - - while (!stack.empty()) - { - SHAMapInnerNode* node; - SHAMapNodeID nodeID; - std::tie (node, nodeID) = stack.top (); - stack.pop (); - - // 1) Add this node to the pack - if (!func (*node)) - return; - - // 2) push non-matching child inner nodes - for (int i = 0; i < 16; ++i) - { - if (!node->isEmptyBranch (i)) - { - auto const& childHash = node->getChildHash (i); - SHAMapNodeID childID = nodeID.getChildNodeID (i); - auto next = descendThrow(node, i); - - if (next->isInner ()) - { - if (!have || !have->hasInnerNode(childID, childHash)) - stack.push ({static_cast(next), childID}); - } - else if (!have || !have->hasLeafNode( - static_cast(next)->peekItem()->key(), - childHash)) - { - if (! func (*next)) - return; - } - } - } - } -} - } // ripple