22 boost::intrusive_ptr<SHAMapItem const>
const& otherMapItem,
32 bool emptyBranch = !otherMapItem;
34 while (!nodeStack.
empty())
36 node = nodeStack.
top();
43 for (
int i = 0; i < 16; ++i)
44 if (!inner->isEmptyBranch(i))
52 if (emptyBranch || (item->key() != otherMapItem->key()))
65 else if (item->slice() != otherMapItem->slice())
70 item->key(),
DeltaRef(item, otherMapItem)));
73 item->key(),
DeltaRef(otherMapItem, item)));
93 otherMapItem->key(), DeltaRef(
nullptr, otherMapItem)));
96 otherMapItem->key(), DeltaRef(otherMapItem,
nullptr)));
106SHAMap::compare(
SHAMap const& otherMap,
Delta& differences,
int maxCount)
const
114 isValid() && otherMap.
isValid(),
115 "ripple::SHAMap::compare : valid state and valid input");
117 if (getHash() == otherMap.
getHash())
124 nodeStack.
push({root_.get(), otherMap.
root_.get()});
125 while (!nodeStack.
empty())
127 auto [ourNode, otherNode] = nodeStack.
top();
130 if (!ourNode || !otherNode)
133 UNREACHABLE(
"ripple::SHAMap::compare : missing a node");
134 Throw<SHAMapMissingNode>(type_,
uint256());
138 if (ourNode->isLeaf() && otherNode->isLeaf())
143 if (ours->peekItem()->key() == other->peekItem()->key())
145 if (ours->peekItem()->slice() != other->peekItem()->slice())
148 ours->peekItem()->key(),
149 DeltaRef(ours->peekItem(), other->peekItem())));
157 ours->peekItem()->key(),
158 DeltaRef(ours->peekItem(),
nullptr)));
163 other->peekItem()->key(),
164 DeltaRef(
nullptr, other->peekItem())));
169 else if (ourNode->isInner() && otherNode->isLeaf())
174 ours, other->peekItem(),
true, differences, maxCount))
177 else if (ourNode->isLeaf() && otherNode->isInner())
182 other, ours->peekItem(),
false, differences, maxCount))
185 else if (ourNode->isInner() && otherNode->isInner())
189 for (
int i = 0; i < 16; ++i)
190 if (ours->getChildHash(i) != other->getChildHash(i))
192 if (other->isEmptyBranch(i))
197 iNode,
nullptr,
true, differences, maxCount))
200 else if (ours->isEmptyBranch(i))
205 iNode,
nullptr,
false, differences, maxCount))
210 {descendThrow(ours, i),
217 UNREACHABLE(
"ripple::SHAMap::compare : invalid node");
229 if (!root_->isInner())
235 nodeStack.
push(intr_ptr::static_pointer_cast<SHAMapInnerNode>(root_));
237 while (!nodeStack.
empty())
242 for (
int i = 0; i < 16; ++i)
244 if (!node->isEmptyBranch(i))
247 descendNoStore(*node, i);
251 if (nextNode->isInner())
253 intr_ptr::static_pointer_cast<SHAMapInnerNode>(
258 missingNodes.
emplace_back(type_, node->getChildHash(i));
259 if (--maxMissing <= 0)
268SHAMap::walkMapParallel(
270 int maxMissing)
const
272 if (!root_->isInner())
278 auto const& innerRoot =
279 intr_ptr::static_pointer_cast<SHAMapInnerNode>(root_);
280 for (
int i = 0; i < 16; ++i)
282 if (!innerRoot->isEmptyBranch(i))
283 topChildren[i] = descendNoStore(*innerRoot, i);
297 for (
int rootChildIndex = 0; rootChildIndex < 16; ++rootChildIndex)
299 auto const& child = topChildren[rootChildIndex];
300 if (!child || !child->isInner())
303 nodeStacks[rootChildIndex].push(
304 intr_ptr::static_pointer_cast<SHAMapInnerNode>(child));
306 JLOG(journal_.debug()) <<
"starting worker " << rootChildIndex;
308 [&m, &missingNodes, &maxMissing, &exceptions,
this](
312 while (!nodeStack.empty())
314 intr_ptr::SharedPtr<SHAMapInnerNode> node =
315 std::move(nodeStack.top());
318 "ripple::SHAMap::walkMapParallel : non-null node");
321 for (int i = 0; i < 16; ++i)
323 if (node->isEmptyBranch(i))
325 intr_ptr::SharedPtr<SHAMapTreeNode> nextNode =
326 descendNoStore(*node, i);
330 if (nextNode->isInner())
332 intr_ptr::static_pointer_cast<
333 SHAMapInnerNode>(nextNode));
337 std::lock_guard l{m};
338 missingNodes.emplace_back(
339 type_, node->getChildHash(i));
340 if (--maxMissing <= 0)
352 std::move(nodeStacks[rootChildIndex])));
359 if (exceptions.empty())
362 ss <<
"Exception(s) in ledger load: ";
363 for (
auto const& e : exceptions)
364 ss << e.what() <<
", ";
365 JLOG(journal_.error()) << ss.
str();