20 #include <ripple/basics/contract.h>
21 #include <ripple/shamap/SHAMap.h>
50 bool emptyBranch = !otherMapItem;
52 while (!nodeStack.
empty())
54 node = nodeStack.
top();
61 for (
int i = 0; i < 16; ++i)
62 if (!inner->isEmptyBranch(i))
70 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)));
128 SHAMap::compare(
SHAMap const& otherMap,
Delta& differences,
int maxCount)
const
135 assert(isValid() && otherMap.
isValid());
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 Throw<SHAMapMissingNode>(type_,
uint256());
156 if (ourNode->isLeaf() && otherNode->isLeaf())
161 if (ours->peekItem()->key() == other->peekItem()->key())
163 if (ours->peekItem()->slice() != other->peekItem()->slice())
166 ours->peekItem()->key(),
167 DeltaRef(ours->peekItem(), other->peekItem())));
175 ours->peekItem()->key(),
183 other->peekItem()->key(),
186 other->peekItem())));
191 else if (ourNode->isInner() && otherNode->isLeaf())
196 ours, other->peekItem(),
true, differences, maxCount))
199 else if (ourNode->isLeaf() && otherNode->isInner())
204 other, ours->peekItem(),
false, differences, maxCount))
207 else if (ourNode->isInner() && otherNode->isInner())
211 for (
int i = 0; i < 16; ++i)
212 if (ours->getChildHash(i) != other->getChildHash(i))
214 if (other->isEmptyBranch(i))
226 else if (ours->isEmptyBranch(i))
240 {descendThrow(ours, i),
255 if (!root_->isInner())
261 nodeStack.
push(std::static_pointer_cast<SHAMapInnerNode>(root_));
263 while (!nodeStack.
empty())
268 for (
int i = 0; i < 16; ++i)
270 if (!node->isEmptyBranch(i))
273 descendNoStore(node, i);
277 if (nextNode->isInner())
279 std::static_pointer_cast<SHAMapInnerNode>(
284 missingNodes.
emplace_back(type_, node->getChildHash(i));
285 if (--maxMissing <= 0)
294 SHAMap::walkMapParallel(
296 int maxMissing)
const
298 if (!root_->isInner())
304 auto const& innerRoot =
305 std::static_pointer_cast<SHAMapInnerNode>(root_);
306 for (
int i = 0; i < 16; ++i)
308 if (!innerRoot->isEmptyBranch(i))
309 topChildren[i] = descendNoStore(innerRoot, i);
323 for (
int rootChildIndex = 0; rootChildIndex < 16; ++rootChildIndex)
325 auto const& child = topChildren[rootChildIndex];
326 if (!child || !child->isInner())
329 nodeStacks[rootChildIndex].push(
330 std::static_pointer_cast<SHAMapInnerNode>(child));
332 JLOG(journal_.debug()) <<
"starting worker " << rootChildIndex;
334 [&m, &missingNodes, &maxMissing, &exceptions,
this](
338 while (!nodeStack.empty())
340 std::shared_ptr<SHAMapInnerNode> node =
341 std::move(nodeStack.top());
345 for (int i = 0; i < 16; ++i)
347 if (node->isEmptyBranch(i))
349 std::shared_ptr<SHAMapTreeNode> nextNode =
350 descendNoStore(node, i);
354 if (nextNode->isInner())
355 nodeStack.push(std::static_pointer_cast<
356 SHAMapInnerNode>(nextNode));
360 std::lock_guard l{m};
361 missingNodes.emplace_back(
362 type_, node->getChildHash(i));
363 if (--maxMissing <= 0)
375 std::move(nodeStacks[rootChildIndex])));
382 if (exceptions.empty())
385 ss <<
"Exception(s) in ledger load: ";
386 for (
auto const& e : exceptions)
387 ss << e.what() <<
", ";
388 JLOG(journal_.error()) << ss.
str();