41 boost::intrusive_ptr<SHAMapItem const>
const& otherMapItem,
51 bool emptyBranch = !otherMapItem;
53 while (!nodeStack.
empty())
55 node = nodeStack.
top();
62 for (
int i = 0; i < 16; ++i)
63 if (!inner->isEmptyBranch(i))
71 if (emptyBranch || (item->key() != otherMapItem->key()))
84 else if (item->slice() != otherMapItem->slice())
89 item->key(),
DeltaRef(item, otherMapItem)));
92 item->key(),
DeltaRef(otherMapItem, item)));
112 otherMapItem->key(), DeltaRef(
nullptr, otherMapItem)));
115 otherMapItem->key(), DeltaRef(otherMapItem,
nullptr)));
125SHAMap::compare(
SHAMap const& otherMap,
Delta& differences,
int maxCount)
const
133 isValid() && otherMap.
isValid(),
134 "ripple::SHAMap::compare : valid state and valid input");
136 if (getHash() == otherMap.
getHash())
143 nodeStack.
push({root_.get(), otherMap.
root_.get()});
144 while (!nodeStack.
empty())
146 auto [ourNode, otherNode] = nodeStack.
top();
149 if (!ourNode || !otherNode)
152 UNREACHABLE(
"ripple::SHAMap::compare : missing a node");
153 Throw<SHAMapMissingNode>(type_,
uint256());
157 if (ourNode->isLeaf() && otherNode->isLeaf())
162 if (ours->peekItem()->key() == other->peekItem()->key())
164 if (ours->peekItem()->slice() != other->peekItem()->slice())
167 ours->peekItem()->key(),
168 DeltaRef(ours->peekItem(), other->peekItem())));
176 ours->peekItem()->key(),
177 DeltaRef(ours->peekItem(),
nullptr)));
182 other->peekItem()->key(),
183 DeltaRef(
nullptr, other->peekItem())));
188 else if (ourNode->isInner() && otherNode->isLeaf())
193 ours, other->peekItem(),
true, differences, maxCount))
196 else if (ourNode->isLeaf() && otherNode->isInner())
201 other, ours->peekItem(),
false, differences, maxCount))
204 else if (ourNode->isInner() && otherNode->isInner())
208 for (
int i = 0; i < 16; ++i)
209 if (ours->getChildHash(i) != other->getChildHash(i))
211 if (other->isEmptyBranch(i))
216 iNode,
nullptr,
true, differences, maxCount))
219 else if (ours->isEmptyBranch(i))
224 iNode,
nullptr,
false, differences, maxCount))
229 {descendThrow(ours, i),
236 UNREACHABLE(
"ripple::SHAMap::compare : invalid node");
248 if (!root_->isInner())
254 nodeStack.
push(intr_ptr::static_pointer_cast<SHAMapInnerNode>(root_));
256 while (!nodeStack.
empty())
261 for (
int i = 0; i < 16; ++i)
263 if (!node->isEmptyBranch(i))
266 descendNoStore(*node, i);
270 if (nextNode->isInner())
272 intr_ptr::static_pointer_cast<SHAMapInnerNode>(
277 missingNodes.
emplace_back(type_, node->getChildHash(i));
278 if (--maxMissing <= 0)
287SHAMap::walkMapParallel(
289 int maxMissing)
const
291 if (!root_->isInner())
297 auto const& innerRoot =
298 intr_ptr::static_pointer_cast<SHAMapInnerNode>(root_);
299 for (
int i = 0; i < 16; ++i)
301 if (!innerRoot->isEmptyBranch(i))
302 topChildren[i] = descendNoStore(*innerRoot, i);
316 for (
int rootChildIndex = 0; rootChildIndex < 16; ++rootChildIndex)
318 auto const& child = topChildren[rootChildIndex];
319 if (!child || !child->isInner())
322 nodeStacks[rootChildIndex].push(
323 intr_ptr::static_pointer_cast<SHAMapInnerNode>(child));
325 JLOG(journal_.debug()) <<
"starting worker " << rootChildIndex;
327 [&m, &missingNodes, &maxMissing, &exceptions,
this](
331 while (!nodeStack.empty())
333 intr_ptr::SharedPtr<SHAMapInnerNode> node =
334 std::move(nodeStack.top());
337 "ripple::SHAMap::walkMapParallel : non-null node");
340 for (int i = 0; i < 16; ++i)
342 if (node->isEmptyBranch(i))
344 intr_ptr::SharedPtr<SHAMapTreeNode> nextNode =
345 descendNoStore(*node, i);
349 if (nextNode->isInner())
351 intr_ptr::static_pointer_cast<
352 SHAMapInnerNode>(nextNode));
356 std::lock_guard l{m};
357 missingNodes.emplace_back(
358 type_, node->getChildHash(i));
359 if (--maxMissing <= 0)
371 std::move(nodeStacks[rootChildIndex])));
378 if (exceptions.empty())
381 ss <<
"Exception(s) in ledger load: ";
382 for (
auto const& e : exceptions)
383 ss << e.what() <<
", ";
384 JLOG(journal_.error()) << ss.
str();