diff --git a/src/ripple_app/shamap/SHAMap.h b/src/ripple_app/shamap/SHAMap.h index 99d0b9493..54d5b76b5 100644 --- a/src/ripple_app/shamap/SHAMap.h +++ b/src/ripple_app/shamap/SHAMap.h @@ -238,6 +238,8 @@ private: bool walkBranch (SHAMapTreeNode * node, SHAMapItem::ref otherMapItem, bool isFirstMap, Delta & differences, int & maxCount); + void visitLeavesInternal (FUNCTION_TYPE& function); + private: #if 1 LockType mLock; diff --git a/src/ripple_app/shamap/SHAMapSync.cpp b/src/ripple_app/shamap/SHAMapSync.cpp index 9f688484f..b7326eb6a 100644 --- a/src/ripple_app/shamap/SHAMapSync.cpp +++ b/src/ripple_app/shamap/SHAMapSync.cpp @@ -25,8 +25,16 @@ KeyCache SHAMap::fullBelowCache ("fullBelowCache", void SHAMap::visitLeaves (FUNCTION_TYPE function) { - ScopedLockType sl (mLock, __FILE__, __LINE__); + SHAMap::pointer snap; + { + ScopedLockType sl (mLock, __FILE__, __LINE__); + snap = snapShot (false); + } + snap->visitLeavesInternal(function); +} +void SHAMap::visitLeavesInternal (FUNCTION_TYPE& function) +{ assert (root->isValid ()); if (!root || root->isEmpty ()) @@ -50,18 +58,21 @@ void SHAMap::visitLeaves (FUNCTION_TYPE function) { if (node->isEmptyBranch (pos)) ++pos; - else + else { SHAMapTreeNode* child = getNodePointer (node->getChildNodeID (pos), node->getChildHash (pos)); if (child->isLeaf ()) { function (child->peekItem ()); + mTNByID.erase (*child); // don't need this leaf anymore ++pos; } else { if (pos != 15) stack.push (posPair (pos + 1, node)); // save next position + else + mTNByID.erase (*node); // don't need this inner node anymore node = child; pos = 0; @@ -72,8 +83,8 @@ void SHAMap::visitLeaves (FUNCTION_TYPE function) if (stack.empty ()) break; pos = stack.top ().first; - node = stack.top ().second; - stack.pop (); + node = stack.top ().second; + stack.pop (); } }