20 #include <ripple/basics/contract.h>
21 #include <ripple/shamap/SHAMap.h>
27 , journal_(f.journal())
32 root_ = std::make_shared<SHAMapInnerNode>(
seq_);
41 , journal_(f.journal())
46 root_ = std::make_shared<SHAMapInnerNode>(
seq_);
57 auto ret = std::make_shared<SHAMap>(
type_,
f_);
92 assert(child && (child->getSeq() ==
seq_));
94 while (!stack.
empty())
97 std::dynamic_pointer_cast<SHAMapInnerNode>(stack.
top().
first);
100 assert(node !=
nullptr);
106 node->setChild(branch, child);
108 child = std::move(node);
115 assert(stack ==
nullptr || stack->
empty());
119 while (inNode->isInner())
121 if (stack !=
nullptr)
122 stack->
push({inNode, nodeID});
124 auto const inner = std::static_pointer_cast<SHAMapInnerNode>(inNode);
126 if (inner->isEmptyBranch(branch))
133 if (stack !=
nullptr)
134 stack->
push({inNode, nodeID});
142 if (leaf && leaf->
peekItem()->key() !=
id)
154 if (
auto nodeObject =
173 const_cast<bool&
>(
full_) =
false;
184 if (
auto nodeData = filter->
getNode(hash))
196 std::move(*nodeData),
206 <<
"Invalid node/data, hash=" << hash <<
": " << x.
what();
255 Throw<SHAMapMissingNode>(
type_, hash);
277 if (!ret && !parent->isEmptyBranch(branch))
278 Throw<SHAMapMissingNode>(
type_, parent->getChildHash(branch));
307 node =
fetchNode(parent->getChildHash(branch));
311 node = parent->canonicalizeChild(branch, std::move(node));
324 ret =
fetchNode(parent->getChildHash(branch));
336 assert((branch >= 0) && (branch < 16));
350 child = childNode.
get();
402 template <
class Node>
407 assert(node->isValid());
408 assert(node->getSeq() <=
seq_);
409 if (node->getSeq() !=
seq_)
413 node = std::static_pointer_cast<Node>(node->clone(
seq_));
414 assert(node->isValid());
430 auto n = std::static_pointer_cast<SHAMapTreeNode>(node);
431 stack.
push({node, {64, n->peekItem()->key()}});
434 auto inner = std::static_pointer_cast<SHAMapInnerNode>(node);
438 stack.
push({inner, stack.
top().second.getChildNodeID(branch)});
439 for (
int i = 0; i < 16;)
441 if (!inner->isEmptyBranch(i))
444 assert(!stack.
empty());
447 auto n = std::static_pointer_cast<SHAMapTreeNode>(node);
448 stack.
push({n, {64, n->peekItem()->key()}});
451 inner = std::static_pointer_cast<SHAMapInnerNode>(node);
452 stack.
push({inner, stack.
top().second.getChildNodeID(branch)});
472 for (
int i = 0; i < 16; ++i)
474 if (!inner->isEmptyBranch(i))
495 assert(leaf->hasItem() || (leaf ==
root_.get()));
497 return leaf->peekItem();
503 assert(stack.
empty());
507 while (!stack.
empty())
517 assert(!stack.
empty());
518 assert(stack.
top().
first->isLeaf());
520 while (!stack.
empty())
522 auto [node, nodeID] = stack.
top();
523 assert(!node->isLeaf());
524 auto inner = std::static_pointer_cast<SHAMapInnerNode>(node);
525 for (
auto i = nodeID.selectBranch(
id) + 1; i < 16; ++i)
527 if (!inner->isEmptyBranch(i))
532 Throw<SHAMapMissingNode>(
type_,
id);
533 assert(leaf->isLeaf());
585 while (!stack.
empty())
587 auto [node, nodeID] = stack.
top();
591 if (leaf->peekItem()->key() > id)
593 this, leaf->peekItem().get(), std::move(stack));
597 auto inner = std::static_pointer_cast<SHAMapInnerNode>(node);
598 for (
auto branch = nodeID.selectBranch(
id) + 1; branch < 16;
601 if (!inner->isEmptyBranch(branch))
606 Throw<SHAMapMissingNode>(
type_,
id);
608 this, leaf->peekItem().get(), std::move(stack));
622 return (leaf !=
nullptr);
635 Throw<SHAMapMissingNode>(
type_,
id);
637 auto leaf = std::dynamic_pointer_cast<SHAMapTreeNode>(stack.
top().
first);
640 if (!leaf || (leaf->peekItem()->key() !=
id))
649 while (!stack.
empty())
652 std::static_pointer_cast<SHAMapInnerNode>(stack.
top().
first);
663 const int bc = node->getBranchCount();
676 for (
int i = 0; i < 16; ++i)
678 if (!node->isEmptyBranch(i))
680 node->setChild(i,
nullptr);
684 prevNode = std::make_shared<SHAMapTreeNode>(
685 item, type, node->getSeq());
689 prevNode = std::move(node);
695 prevNode = std::move(node);
722 Throw<SHAMapMissingNode>(
type_, tag);
724 auto [node, nodeID] = stack.
top();
729 auto leaf = std::static_pointer_cast<SHAMapTreeNode>(node);
730 if (leaf->peekItem()->key() == tag)
737 auto inner = std::static_pointer_cast<SHAMapInnerNode>(node);
738 int branch = nodeID.selectBranch(tag);
739 assert(inner->isEmptyBranch(branch));
741 std::make_shared<SHAMapTreeNode>(std::move(item), type,
seq_);
742 inner->setChild(branch, newNode);
748 auto leaf = std::static_pointer_cast<SHAMapTreeNode>(node);
750 assert(otherItem && (tag != otherItem->key()));
752 node = std::make_shared<SHAMapInnerNode>(node->getSeq());
756 while ((b1 = nodeID.selectBranch(tag)) ==
757 (b2 = nodeID.selectBranch(otherItem->key())))
759 stack.
push({node, nodeID});
763 nodeID = nodeID.getChildNodeID(b1);
764 node = std::make_shared<SHAMapInnerNode>(
seq_);
768 assert(node->isInner());
771 std::make_shared<SHAMapTreeNode>(std::move(item), type,
seq_);
772 assert(newNode->isValid() && newNode->isLeaf());
773 auto inner = std::static_pointer_cast<SHAMapInnerNode>(node);
774 inner->setChild(b1, newNode);
777 std::make_shared<SHAMapTreeNode>(std::move(otherItem), type,
seq_);
778 assert(newNode->isValid() && newNode->isLeaf());
779 inner->setChild(b2, newNode);
790 std::make_shared<SHAMapItem const>(std::move(i)),
798 auto hash =
root_->getNodeHash();
802 hash =
root_->getNodeHash();
822 Throw<SHAMapMissingNode>(
type_, tag);
824 auto node = std::dynamic_pointer_cast<SHAMapTreeNode>(stack.
top().
first);
828 if (!node || (node->peekItem()->key() != tag))
853 if (hash ==
root_->getNodeHash())
860 stream <<
"Fetch root TXN node " << hash;
864 stream <<
"Fetch root STATE node " << hash;
868 stream <<
"Fetch root SHAMap node " << hash;
877 assert(
root_->getNodeHash() == hash);
900 assert(node->getSeq() ==
seq_);
911 node->getNodeHash().as_uint256(),
919 template <
class Node>
925 assert(node->getSeq() != 0);
927 if (node->getSeq() !=
seq_)
931 node = std::static_pointer_cast<Node>(node->clone(
seq_));
971 auto node = std::static_pointer_cast<SHAMapInnerNode>(
root_);
975 root_ = std::make_shared<SHAMapInnerNode>(0);
993 if (node->isEmptyBranch(pos))
1002 auto child = node->getChild(pos++);
1004 if (child && (child->getSeq() != 0))
1010 if (child->isInner())
1014 stack.
emplace(std::move(node), branch);
1018 node = std::static_pointer_cast<SHAMapInnerNode>(
1027 assert(node->getSeq() ==
seq_);
1028 child->updateHash();
1031 child =
writeNode(t, seq, std::move(child));
1035 node->shareChild(branch, child);
1042 node->updateHashDeep();
1046 node = std::static_pointer_cast<SHAMapInnerNode>(
1056 auto parent = std::move(stack.
top().first);
1057 pos = stack.
top().second;
1061 assert(parent->getSeq() ==
seq_);
1062 parent->shareChild(pos, node);
1065 node = std::move(parent);
1070 root_ = std::move(node);
1086 auto [node, nodeID] = stack.
top();
1092 JLOG(
journal_.
info()) <<
"Hash: " << node->getNodeHash();
1095 if (node->isInner())
1098 for (
int i = 0; i < 16; ++i)
1100 if (!inner->isEmptyBranch(i))
1102 auto child = inner->getChildPointer(i);
1105 assert(child->getNodeHash() == inner->getChildHash(i));
1106 stack.
push({child, nodeID.getChildNodeID(i)});
1113 }
while (!stack.
empty());
1115 JLOG(
journal_.
info()) << leafCount <<
" resident leaves";
1122 assert(!ret || !ret->getSeq());
1132 assert(node->getSeq() == 0);
1133 assert(node->getNodeHash() == hash);
1136 ->canonicalize_replace_client(hash.
as_uint256(), node);
1143 auto node =
root_.get();
1144 assert(node !=
nullptr);
1145 assert(!node->isLeaf());
1150 node->invariants(
true);