42 boost::intrusive_ptr<SHAMapItem const>
const& otherMapItem,
52 bool emptyBranch = !otherMapItem;
54 while (!nodeStack.
empty())
56 node = nodeStack.
top();
63 for (
int i = 0; i < 16; ++i)
64 if (!inner->isEmptyBranch(i))
72 if (emptyBranch || (item->key() != otherMapItem->key()))
85 else if (item->slice() != otherMapItem->slice())
90 item->key(),
DeltaRef(item, otherMapItem)));
93 item->key(),
DeltaRef(otherMapItem, item)));
113 otherMapItem->key(), DeltaRef(
nullptr, otherMapItem)));
116 otherMapItem->key(), DeltaRef(otherMapItem,
nullptr)));
126SHAMap::compare(
SHAMap const& otherMap,
Delta& differences,
int maxCount)
const
134 isValid() && otherMap.
isValid(),
135 "ripple::SHAMap::compare : valid state and valid input");
137 if (getHash() == otherMap.
getHash())
144 nodeStack.
push({root_.get(), otherMap.
root_.get()});
145 while (!nodeStack.
empty())
147 auto [ourNode, otherNode] = nodeStack.
top();
150 if (!ourNode || !otherNode)
153 UNREACHABLE(
"ripple::SHAMap::compare : missing a node");
154 Throw<SHAMapMissingNode>(type_,
uint256());
158 if (ourNode->isLeaf() && otherNode->isLeaf())
163 if (ours->peekItem()->key() == other->peekItem()->key())
165 if (ours->peekItem()->slice() != other->peekItem()->slice())
168 ours->peekItem()->key(),
169 DeltaRef(ours->peekItem(), other->peekItem())));
177 ours->peekItem()->key(),
178 DeltaRef(ours->peekItem(),
nullptr)));
183 other->peekItem()->key(),
184 DeltaRef(
nullptr, other->peekItem())));
189 else if (ourNode->isInner() && otherNode->isLeaf())
194 ours, other->peekItem(),
true, differences, maxCount))
197 else if (ourNode->isLeaf() && otherNode->isInner())
202 other, ours->peekItem(),
false, differences, maxCount))
205 else if (ourNode->isInner() && otherNode->isInner())
209 for (
int i = 0; i < 16; ++i)
210 if (ours->getChildHash(i) != other->getChildHash(i))
212 if (other->isEmptyBranch(i))
217 iNode,
nullptr,
true, differences, maxCount))
220 else if (ours->isEmptyBranch(i))
225 iNode,
nullptr,
false, differences, maxCount))
230 {descendThrow(ours, i),
237 UNREACHABLE(
"ripple::SHAMap::compare : invalid node");
249 if (!root_->isInner())
255 nodeStack.
push(intr_ptr::static_pointer_cast<SHAMapInnerNode>(root_));
257 while (!nodeStack.
empty())
262 for (
int i = 0; i < 16; ++i)
264 if (!node->isEmptyBranch(i))
267 descendNoStore(*node, i);
271 if (nextNode->isInner())
273 intr_ptr::static_pointer_cast<SHAMapInnerNode>(
278 missingNodes.
emplace_back(type_, node->getChildHash(i));
279 if (--maxMissing <= 0)
288SHAMap::walkMapParallel(
290 int maxMissing)
const
292 if (!root_->isInner())
298 auto const& innerRoot =
299 intr_ptr::static_pointer_cast<SHAMapInnerNode>(root_);
300 for (
int i = 0; i < 16; ++i)
302 if (!innerRoot->isEmptyBranch(i))
303 topChildren[i] = descendNoStore(*innerRoot, i);
317 for (
int rootChildIndex = 0; rootChildIndex < 16; ++rootChildIndex)
319 auto const& child = topChildren[rootChildIndex];
320 if (!child || !child->isInner())
323 nodeStacks[rootChildIndex].push(
324 intr_ptr::static_pointer_cast<SHAMapInnerNode>(child));
326 JLOG(journal_.debug()) <<
"starting worker " << rootChildIndex;
328 [&m, &missingNodes, &maxMissing, &exceptions,
this](
332 while (!nodeStack.empty())
334 intr_ptr::SharedPtr<SHAMapInnerNode> node =
335 std::move(nodeStack.top());
338 "ripple::SHAMap::walkMapParallel : non-null node");
341 for (int i = 0; i < 16; ++i)
343 if (node->isEmptyBranch(i))
345 intr_ptr::SharedPtr<SHAMapTreeNode> nextNode =
346 descendNoStore(*node, i);
350 if (nextNode->isInner())
352 intr_ptr::static_pointer_cast<
353 SHAMapInnerNode>(nextNode));
357 std::lock_guard l{m};
358 missingNodes.emplace_back(
359 type_, node->getChildHash(i));
360 if (--maxMissing <= 0)
372 std::move(nodeStacks[rootChildIndex])));
379 if (exceptions.empty())
382 ss <<
"Exception(s) in ledger load: ";
383 for (
auto const& e : exceptions)
384 ss << e.what() <<
", ";
385 JLOG(journal_.error()) << ss.
str();