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();