23 boost::intrusive_ptr<SHAMapItem const>
const& otherMapItem,
33 bool emptyBranch = !otherMapItem;
35 while (!nodeStack.
empty())
37 node = nodeStack.
top();
43 auto inner = safe_downcast<SHAMapInnerNode*>(node);
44 for (
int i = 0; i < 16; ++i)
46 if (!inner->isEmptyBranch(i))
53 auto item = safe_downcast<SHAMapLeafNode*>(node)->peekItem();
55 if (emptyBranch || (item->key() != otherMapItem->key()))
70 else if (item->slice() != otherMapItem->slice())
125 isValid() && otherMap.
isValid(),
"xrpl::SHAMap::compare : valid state and valid input");
134 while (!nodeStack.
empty())
136 auto [ourNode, otherNode] = nodeStack.
top();
139 if ((ourNode ==
nullptr) || (otherNode ==
nullptr))
142 UNREACHABLE(
"xrpl::SHAMap::compare : missing a node");
147 if (ourNode->isLeaf() && otherNode->isLeaf())
150 auto ours = safe_downcast<SHAMapLeafNode*>(ourNode);
151 auto other = safe_downcast<SHAMapLeafNode*>(otherNode);
152 if (ours->peekItem()->key() == other->peekItem()->key())
154 if (ours->peekItem()->slice() != other->peekItem()->slice())
158 ours->peekItem()->key(),
159 DeltaRef(ours->peekItem(), other->peekItem())));
177 else if (ourNode->isInner() && otherNode->isLeaf())
179 auto ours = safe_downcast<SHAMapInnerNode*>(ourNode);
180 auto other = safe_downcast<SHAMapLeafNode*>(otherNode);
181 if (!
walkBranch(ours, other->peekItem(),
true, differences, maxCount))
184 else if (ourNode->isLeaf() && otherNode->isInner())
186 auto ours = safe_downcast<SHAMapLeafNode*>(ourNode);
187 auto other = safe_downcast<SHAMapInnerNode*>(otherNode);
188 if (!otherMap.
walkBranch(other, ours->peekItem(),
false, differences, maxCount))
191 else if (ourNode->isInner() && otherNode->isInner())
193 auto ours = safe_downcast<SHAMapInnerNode*>(ourNode);
194 auto other = safe_downcast<SHAMapInnerNode*>(otherNode);
195 for (
int i = 0; i < 16; ++i)
197 if (ours->getChildHash(i) != other->getChildHash(i))
199 if (other->isEmptyBranch(i))
203 if (!
walkBranch(iNode,
nullptr,
true, differences, maxCount))
206 else if (ours->isEmptyBranch(i))
210 if (!otherMap.
walkBranch(iNode,
nullptr,
false, differences, maxCount))
223 UNREACHABLE(
"xrpl::SHAMap::compare : invalid node");
272 if (!
root_->isInner())
278 auto const& innerRoot = intr_ptr::static_pointer_cast<SHAMapInnerNode>(
root_);
279 for (
int i = 0; i < 16; ++i)
281 if (!innerRoot->isEmptyBranch(i))
296 for (
int rootChildIndex = 0; rootChildIndex < 16; ++rootChildIndex)
298 auto const& child = topChildren[rootChildIndex];
299 if (!child || !child->isInner())
302 nodeStacks[rootChildIndex].push(intr_ptr::static_pointer_cast<SHAMapInnerNode>(child));
304 JLOG(
journal_.
debug()) <<
"starting worker " << rootChildIndex;
307 [&m, &missingNodes, &maxMissing, &exceptions,
this](
311 while (!nodeStack.empty())
313 intr_ptr::SharedPtr<SHAMapInnerNode> const node =
314 std::move(nodeStack.top());
315 XRPL_ASSERT(node,
"xrpl::SHAMap::walkMapParallel : non-null node");
318 for (int i = 0; i < 16; ++i)
320 if (node->isEmptyBranch(i))
322 intr_ptr::SharedPtr<SHAMapTreeNode> const nextNode =
323 descendNoStore(*node, i);
327 if (nextNode->isInner())
330 intr_ptr::static_pointer_cast<SHAMapInnerNode>(
336 std::lock_guard const l{m};
337 missingNodes.emplace_back(type_, node->getChildHash(i));
338 if (--maxMissing <= 0)
350 std::move(nodeStacks[rootChildIndex])));
357 if (exceptions.empty())
360 ss <<
"Exception(s) in ledger load: ";
361 for (
auto const& e : exceptions)
362 ss << e.what() <<
", ";
363 JLOG(journal_.error()) << ss.
str();
bool walkBranch(SHAMapTreeNode *node, boost::intrusive_ptr< SHAMapItem const > const &otherMapItem, bool isFirstMap, Delta &differences, int &maxCount) const