mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-21 14:20:56 +00:00
refactor: Use unsigned int for branch-related operations (#7938)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -484,31 +484,36 @@ private:
|
||||
|
||||
// returns the first item at or below this node
|
||||
SHAMapLeafNode*
|
||||
firstBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, int branch = 0) const;
|
||||
firstBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, unsigned int branch = 0u) const;
|
||||
|
||||
// returns the last item at or below this node
|
||||
SHAMapLeafNode*
|
||||
lastBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, int branch = kBranchFactor) const;
|
||||
lastBelow(
|
||||
SHAMapTreeNodePtr node,
|
||||
SharedPtrNodeStack& stack,
|
||||
unsigned int branch = kBranchFactor) const;
|
||||
|
||||
// direction in which belowHelper scans an inner node's branches
|
||||
enum class BelowDirection { First, Last };
|
||||
|
||||
// helper function for firstBelow and lastBelow
|
||||
SHAMapLeafNode*
|
||||
belowHelper(
|
||||
SHAMapTreeNodePtr node,
|
||||
SharedPtrNodeStack& stack,
|
||||
int branch,
|
||||
std::tuple<int, std::function<bool(int)>, std::function<void(int&)>> const& loopParams)
|
||||
const;
|
||||
unsigned int branch,
|
||||
BelowDirection direction) const;
|
||||
|
||||
// Simple descent
|
||||
// Get a child of the specified node
|
||||
SHAMapTreeNode*
|
||||
descend(SHAMapInnerNode*, int branch) const;
|
||||
descend(SHAMapInnerNode*, unsigned int branch) const;
|
||||
SHAMapTreeNode*
|
||||
descendThrow(SHAMapInnerNode*, int branch) const;
|
||||
descendThrow(SHAMapInnerNode*, unsigned int branch) const;
|
||||
SHAMapTreeNodePtr
|
||||
descend(SHAMapInnerNode&, int branch) const;
|
||||
descend(SHAMapInnerNode&, unsigned int branch) const;
|
||||
SHAMapTreeNodePtr
|
||||
descendThrow(SHAMapInnerNode&, int branch) const;
|
||||
descendThrow(SHAMapInnerNode&, unsigned int branch) const;
|
||||
|
||||
// Descend with filter
|
||||
// If pending, callback is called as if it called fetchNodeNT
|
||||
@@ -516,7 +521,7 @@ private:
|
||||
SHAMapTreeNode*
|
||||
descendAsync(
|
||||
SHAMapInnerNode* parent,
|
||||
int branch,
|
||||
unsigned int branch,
|
||||
SHAMapSyncFilter const* filter,
|
||||
bool& pending,
|
||||
descendCallback&&) const;
|
||||
@@ -525,13 +530,13 @@ private:
|
||||
descend(
|
||||
SHAMapInnerNode* parent,
|
||||
SHAMapNodeID const& parentID,
|
||||
int branch,
|
||||
unsigned int branch,
|
||||
SHAMapSyncFilter const* filter) const;
|
||||
|
||||
// Non-storing
|
||||
// Does not hook the returned node to its parent
|
||||
SHAMapTreeNodePtr
|
||||
descendNoStore(SHAMapInnerNode&, int branch) const;
|
||||
descendNoStore(SHAMapInnerNode&, unsigned int branch) const;
|
||||
|
||||
/**
|
||||
* If there is only one leaf below this node, get its contents
|
||||
@@ -581,8 +586,8 @@ private:
|
||||
using StackEntry = std::tuple<
|
||||
SHAMapInnerNode*, // pointer to the node
|
||||
SHAMapNodeID, // the node's ID
|
||||
int, // while child we check first
|
||||
int, // which child we check next
|
||||
unsigned int, // which child we check first
|
||||
unsigned int, // which child we check next
|
||||
bool>; // whether we've found any missing children yet
|
||||
|
||||
// We explicitly choose to specify the use of std::deque here, because
|
||||
@@ -596,7 +601,7 @@ private:
|
||||
using DeferredNode = std::tuple<
|
||||
SHAMapInnerNode*, // parent node
|
||||
SHAMapNodeID, // parent node ID
|
||||
int, // branch
|
||||
unsigned int, // branch
|
||||
SHAMapTreeNodePtr>; // node
|
||||
|
||||
int deferred;
|
||||
|
||||
@@ -62,8 +62,8 @@ private:
|
||||
*
|
||||
* @param i index of the requested child
|
||||
*/
|
||||
std::optional<int>
|
||||
getChildIndex(int i) const;
|
||||
std::optional<unsigned int>
|
||||
getChildIndex(unsigned int i) const;
|
||||
|
||||
/**
|
||||
* Call the `f` callback for all 16 (branchFactor) branches - even if
|
||||
@@ -125,28 +125,28 @@ public:
|
||||
isEmpty() const;
|
||||
|
||||
bool
|
||||
isEmptyBranch(int m) const;
|
||||
isEmptyBranch(unsigned int branch) const;
|
||||
|
||||
int
|
||||
unsigned int
|
||||
getBranchCount() const;
|
||||
|
||||
SHAMapHash const&
|
||||
getChildHash(int m) const;
|
||||
getChildHash(unsigned int branch) const;
|
||||
|
||||
void
|
||||
setChild(int m, SHAMapTreeNodePtr child);
|
||||
setChild(unsigned int branch, SHAMapTreeNodePtr child);
|
||||
|
||||
void
|
||||
shareChild(int m, SHAMapTreeNodePtr const& child);
|
||||
shareChild(unsigned int branch, SHAMapTreeNodePtr const& child);
|
||||
|
||||
SHAMapTreeNode*
|
||||
getChildPointer(int branch);
|
||||
getChildPointer(unsigned int branch);
|
||||
|
||||
SHAMapTreeNodePtr
|
||||
getChild(int branch);
|
||||
getChild(unsigned int branch);
|
||||
|
||||
SHAMapTreeNodePtr
|
||||
canonicalizeChild(int branch, SHAMapTreeNodePtr node);
|
||||
canonicalizeChild(unsigned int branch, SHAMapTreeNodePtr node);
|
||||
|
||||
// sync functions
|
||||
bool
|
||||
@@ -190,12 +190,12 @@ SHAMapInnerNode::isEmpty() const
|
||||
}
|
||||
|
||||
inline bool
|
||||
SHAMapInnerNode::isEmptyBranch(int m) const
|
||||
SHAMapInnerNode::isEmptyBranch(unsigned int branch) const
|
||||
{
|
||||
return (isBranch_ & (1 << m)) == 0;
|
||||
return (isBranch_ & (1u << branch)) == 0u;
|
||||
}
|
||||
|
||||
inline int
|
||||
inline unsigned int
|
||||
SHAMapInnerNode::getBranchCount() const
|
||||
{
|
||||
return popcnt16(isBranch_);
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]] SHAMapNodeID
|
||||
getChildNodeID(unsigned int m) const;
|
||||
getChildNodeID(unsigned int branch) const;
|
||||
|
||||
/**
|
||||
* Create a SHAMapNodeID of a node with the depth of the node and
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
* @return SHAMapNodeID of the node
|
||||
*/
|
||||
static SHAMapNodeID
|
||||
createID(int depth, uint256 const& key);
|
||||
createID(unsigned int depth, uint256 const& key);
|
||||
|
||||
/**
|
||||
* Comparison operators
|
||||
|
||||
@@ -219,11 +219,11 @@ public:
|
||||
*
|
||||
* @param i index of the requested child
|
||||
*/
|
||||
[[nodiscard]] std::optional<int>
|
||||
getChildIndex(std::uint16_t isBranch, int i) const;
|
||||
[[nodiscard]] std::optional<unsigned int>
|
||||
getChildIndex(std::uint16_t isBranch, unsigned int i) const;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline int
|
||||
[[nodiscard]] inline unsigned int
|
||||
popcnt16(std::uint16_t a)
|
||||
{
|
||||
#if __cpp_lib_bitops
|
||||
@@ -234,11 +234,11 @@ popcnt16(std::uint16_t a)
|
||||
// fallback to table lookup
|
||||
static constexpr auto tbl = []() {
|
||||
std::array<std::uint8_t, 256> ret{};
|
||||
for (int i = 0; i != 256; ++i)
|
||||
for (auto i = 0u; i != 256u; ++i)
|
||||
{
|
||||
for (int j = 0; j != 8; ++j)
|
||||
for (auto j = 0u; j != 8u; ++j)
|
||||
{
|
||||
if (i & (1 << j))
|
||||
if (i & (1u << j))
|
||||
ret[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ static_assert(
|
||||
static_assert(
|
||||
kBoundaries.back() == SHAMapInnerNode::kBranchFactor,
|
||||
"Last element of boundaries must be number of children in a dense array");
|
||||
static_assert(
|
||||
kBoundaries.front() >= 1,
|
||||
"TaggedPointer.ipp subtracts 1 from a numAllocated value derived from "
|
||||
"kBoundaries, as an unsigned quantity, in several places; the smallest "
|
||||
"boundary must stay non-zero or those subtractions underflow.");
|
||||
|
||||
// Terminology: A chunk is the memory being allocated from a block. A block
|
||||
// contains multiple chunks. This is the terminology the boost documentation
|
||||
@@ -148,16 +153,16 @@ TaggedPointer::iterChildren(std::uint16_t isBranch, F&& f) const
|
||||
if (numAllocated == SHAMapInnerNode::kBranchFactor)
|
||||
{
|
||||
// dense case
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
f(hashes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// sparse case
|
||||
int curHashI = 0;
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
auto curHashI = 0u;
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if ((1 << i) & isBranch)
|
||||
if ((1u << i) & isBranch)
|
||||
{
|
||||
f(hashes[curHashI++]);
|
||||
}
|
||||
@@ -176,9 +181,9 @@ TaggedPointer::iterNonEmptyChildIndexes(std::uint16_t isBranch, F&& f) const
|
||||
if (capacity() == SHAMapInnerNode::kBranchFactor)
|
||||
{
|
||||
// dense case
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if ((1 << i) & isBranch)
|
||||
if ((1u << i) & isBranch)
|
||||
{
|
||||
f(i, i);
|
||||
}
|
||||
@@ -187,10 +192,10 @@ TaggedPointer::iterNonEmptyChildIndexes(std::uint16_t isBranch, F&& f) const
|
||||
else
|
||||
{
|
||||
// sparse case
|
||||
int curHashI = 0;
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
auto curHashI = 0u;
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if ((1 << i) & isBranch)
|
||||
if ((1u << i) & isBranch)
|
||||
{
|
||||
f(i, curHashI++);
|
||||
}
|
||||
@@ -216,14 +221,14 @@ TaggedPointer::destroyHashesAndChildren()
|
||||
deallocateArrays(tag, ptr);
|
||||
}
|
||||
|
||||
inline std::optional<int>
|
||||
TaggedPointer::getChildIndex(std::uint16_t isBranch, int i) const
|
||||
inline std::optional<unsigned int>
|
||||
TaggedPointer::getChildIndex(std::uint16_t isBranch, unsigned int i) const
|
||||
{
|
||||
if (isDense())
|
||||
return i;
|
||||
|
||||
// Sparse case
|
||||
if ((isBranch & (1 << i)) == 0)
|
||||
if ((isBranch & (1u << i)) == 0u)
|
||||
{
|
||||
// Empty branch. Sparse children do not store empty branches
|
||||
return {};
|
||||
@@ -273,10 +278,10 @@ inline TaggedPointer::TaggedPointer(
|
||||
*this = std::move(other);
|
||||
auto [srcDstNumAllocated, srcDstHashes, srcDstChildren] = getHashesAndChildren();
|
||||
bool const srcDstIsDense = isDense();
|
||||
int srcDstIndex = 0;
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
auto srcDstIndex = 0u;
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
auto const mask = (1 << i);
|
||||
auto const mask = (1u << i);
|
||||
bool const inSrc = (srcBranches & mask) != 0;
|
||||
bool const inDst = (dstBranches & mask) != 0;
|
||||
if (inSrc && inDst)
|
||||
@@ -298,13 +303,13 @@ inline TaggedPointer::TaggedPointer(
|
||||
// sparse
|
||||
// need to shift all the elements to the left by
|
||||
// one
|
||||
for (int c = srcDstIndex; c < srcDstNumAllocated - 1; ++c)
|
||||
for (auto c = srcDstIndex; c + 1 < srcDstNumAllocated; ++c)
|
||||
{
|
||||
srcDstHashes[c] = srcDstHashes[c + 1];
|
||||
srcDstChildren[c] = std::move(srcDstChildren[c + 1]);
|
||||
}
|
||||
srcDstHashes[srcDstNumAllocated - 1].zero();
|
||||
srcDstChildren[srcDstNumAllocated - 1].reset();
|
||||
srcDstHashes[srcDstNumAllocated - 1u].zero();
|
||||
srcDstChildren[srcDstNumAllocated - 1u].reset();
|
||||
// do not increment the index
|
||||
}
|
||||
}
|
||||
@@ -321,7 +326,7 @@ inline TaggedPointer::TaggedPointer(
|
||||
// sparse
|
||||
// need to create a hole by shifting all the elements to the
|
||||
// right by one
|
||||
for (int c = srcDstNumAllocated - 1; c > srcDstIndex; --c)
|
||||
for (auto c = srcDstNumAllocated - 1u; c > srcDstIndex; --c)
|
||||
{
|
||||
srcDstHashes[c] = srcDstHashes[c - 1];
|
||||
srcDstChildren[c] = std::move(srcDstChildren[c - 1]);
|
||||
@@ -352,10 +357,10 @@ inline TaggedPointer::TaggedPointer(
|
||||
auto [srcNumAllocated, srcHashes, srcChildren] = src.getHashesAndChildren();
|
||||
bool const srcIsDense = src.isDense();
|
||||
bool const dstIsDense = dst.isDense();
|
||||
int srcIndex = 0, dstIndex = 0;
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
auto srcIndex = 0u, dstIndex = 0u;
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
auto const mask = (1 << i);
|
||||
auto const mask = (1u << i);
|
||||
bool const inSrc = (srcBranches & mask) != 0;
|
||||
bool const inDst = (dstBranches & mask) != 0;
|
||||
if (inSrc && inDst)
|
||||
@@ -409,7 +414,7 @@ inline TaggedPointer::TaggedPointer(
|
||||
!dstIsDense || dstIndex == dstNumAllocated,
|
||||
"xrpl::TaggedPointer::TaggedPointer(TaggedPointer&& ...) : "
|
||||
"non-sparse or valid sparse");
|
||||
for (int i = dstIndex; i < dstNumAllocated; ++i)
|
||||
for (auto i = dstIndex; i < dstNumAllocated; ++i)
|
||||
{
|
||||
new (&dstHashes[i]) SHAMapHash{};
|
||||
new (&dstChildren[i]) SHAMapTreeNodePtr{};
|
||||
@@ -448,9 +453,9 @@ inline TaggedPointer::TaggedPointer(
|
||||
new (&newChildren[branchNum]) SHAMapTreeNodePtr{std::move(oldChildren[indexNum])};
|
||||
});
|
||||
// Run the constructors for the remaining elements
|
||||
for (int i = 0; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if (((1 << i) & isBranch) != 0)
|
||||
if (((1u << i) & isBranch) != 0u)
|
||||
continue;
|
||||
new (&newHashes[i]) SHAMapHash{};
|
||||
new (&newChildren[i]) SHAMapTreeNodePtr{};
|
||||
@@ -459,7 +464,7 @@ inline TaggedPointer::TaggedPointer(
|
||||
else
|
||||
{
|
||||
// new arrays are sparse, old arrays may be sparse or dense
|
||||
int curCompressedIndex = 0;
|
||||
auto curCompressedIndex = 0u;
|
||||
iterNonEmptyChildIndexes(isBranch, [&](auto branchNum, auto indexNum) {
|
||||
new (&newHashes[curCompressedIndex]) SHAMapHash{oldHashes[indexNum]};
|
||||
new (&newChildren[curCompressedIndex])
|
||||
@@ -467,7 +472,7 @@ inline TaggedPointer::TaggedPointer(
|
||||
++curCompressedIndex;
|
||||
});
|
||||
// Run the constructors for the remaining elements
|
||||
for (int i = curCompressedIndex; i < newNumAllocated; ++i)
|
||||
for (auto i = curCompressedIndex; i < newNumAllocated; ++i)
|
||||
{
|
||||
new (&newHashes[i]) SHAMapHash{};
|
||||
new (&newChildren[i]) SHAMapTreeNodePtr{};
|
||||
|
||||
@@ -116,8 +116,7 @@ SHAMap::dirtyUp(SharedPtrNodeStack& stack, uint256 const& target, SHAMapTreeNode
|
||||
stack.pop();
|
||||
XRPL_ASSERT(node, "xrpl::SHAMap::dirtyUp : non-null node");
|
||||
|
||||
int const branch = selectBranch(nodeID, target);
|
||||
XRPL_ASSERT(branch >= 0, "xrpl::SHAMap::dirtyUp : valid branch");
|
||||
auto const branch = selectBranch(nodeID, target);
|
||||
|
||||
node = unshareNode(std::move(node), nodeID);
|
||||
node->setChild(branch, std::move(child));
|
||||
@@ -278,7 +277,7 @@ SHAMap::fetchNode(SHAMapHash const& hash) const
|
||||
}
|
||||
|
||||
SHAMapTreeNode*
|
||||
SHAMap::descendThrow(SHAMapInnerNode* parent, int branch) const
|
||||
SHAMap::descendThrow(SHAMapInnerNode* parent, unsigned int branch) const
|
||||
{
|
||||
SHAMapTreeNode* ret = descend(parent, branch); // NOLINT(misc-const-correctness)
|
||||
|
||||
@@ -289,7 +288,7 @@ SHAMap::descendThrow(SHAMapInnerNode* parent, int branch) const
|
||||
}
|
||||
|
||||
SHAMapTreeNodePtr
|
||||
SHAMap::descendThrow(SHAMapInnerNode& parent, int branch) const
|
||||
SHAMap::descendThrow(SHAMapInnerNode& parent, unsigned int branch) const
|
||||
{
|
||||
SHAMapTreeNodePtr ret = descend(parent, branch);
|
||||
|
||||
@@ -300,7 +299,7 @@ SHAMap::descendThrow(SHAMapInnerNode& parent, int branch) const
|
||||
}
|
||||
|
||||
SHAMapTreeNode*
|
||||
SHAMap::descend(SHAMapInnerNode* parent, int branch) const
|
||||
SHAMap::descend(SHAMapInnerNode* parent, unsigned int branch) const
|
||||
{
|
||||
SHAMapTreeNode* ret = parent->getChildPointer(branch); // NOLINT(misc-const-correctness)
|
||||
if ((ret != nullptr) || !backed_)
|
||||
@@ -315,7 +314,7 @@ SHAMap::descend(SHAMapInnerNode* parent, int branch) const
|
||||
}
|
||||
|
||||
SHAMapTreeNodePtr
|
||||
SHAMap::descend(SHAMapInnerNode& parent, int branch) const
|
||||
SHAMap::descend(SHAMapInnerNode& parent, unsigned int branch) const
|
||||
{
|
||||
SHAMapTreeNodePtr node = parent.getChild(branch);
|
||||
if (node || !backed_)
|
||||
@@ -332,7 +331,7 @@ SHAMap::descend(SHAMapInnerNode& parent, int branch) const
|
||||
// Gets the node that would be hooked to this branch,
|
||||
// but doesn't hook it up.
|
||||
SHAMapTreeNodePtr
|
||||
SHAMap::descendNoStore(SHAMapInnerNode& parent, int branch) const
|
||||
SHAMap::descendNoStore(SHAMapInnerNode& parent, unsigned int branch) const
|
||||
{
|
||||
SHAMapTreeNodePtr ret = parent.getChild(branch);
|
||||
if (!ret && backed_)
|
||||
@@ -344,12 +343,11 @@ std::pair<SHAMapTreeNode*, SHAMapNodeID>
|
||||
SHAMap::descend(
|
||||
SHAMapInnerNode* parent,
|
||||
SHAMapNodeID const& parentID,
|
||||
int branch,
|
||||
unsigned int branch,
|
||||
SHAMapSyncFilter const* filter) const
|
||||
{
|
||||
XRPL_ASSERT(parent->isInner(), "xrpl::SHAMap::descend : valid parent input");
|
||||
XRPL_ASSERT(
|
||||
(branch >= 0) && (branch < kBranchFactor), "xrpl::SHAMap::descend : valid branch input");
|
||||
XRPL_ASSERT(branch < kBranchFactor, "xrpl::SHAMap::descend : valid branch input");
|
||||
XRPL_ASSERT(
|
||||
!parent->isEmptyBranch(branch), "xrpl::SHAMap::descend : parent branch is non-empty");
|
||||
|
||||
@@ -373,7 +371,7 @@ SHAMap::descend(
|
||||
SHAMapTreeNode*
|
||||
SHAMap::descendAsync(
|
||||
SHAMapInnerNode* parent,
|
||||
int branch,
|
||||
unsigned int branch,
|
||||
SHAMapSyncFilter const* filter,
|
||||
bool& pending,
|
||||
descendCallback&& callback) const
|
||||
@@ -433,10 +431,9 @@ SHAMapLeafNode*
|
||||
SHAMap::belowHelper(
|
||||
SHAMapTreeNodePtr node,
|
||||
SharedPtrNodeStack& stack,
|
||||
int branch,
|
||||
std::tuple<int, std::function<bool(int)>, std::function<void(int&)>> const& loopParams) const
|
||||
unsigned int branch,
|
||||
BelowDirection direction) const
|
||||
{
|
||||
auto& [init, cmp, incr] = loopParams;
|
||||
if (node->isLeaf())
|
||||
{
|
||||
auto n = intr_ptr::staticPointerCast<SHAMapLeafNode>(node);
|
||||
@@ -452,11 +449,16 @@ SHAMap::belowHelper(
|
||||
{
|
||||
stack.emplace(inner, stack.top().second.getChildNodeID(branch));
|
||||
}
|
||||
for (int i = init; cmp(i);)
|
||||
// `scanned` counts how many branches of `inner` we have examined; the branch we look at is
|
||||
// derived from it, so no index ever goes out of range.
|
||||
for (auto scanned = 0u; scanned < kBranchFactor;)
|
||||
{
|
||||
if (!inner->isEmptyBranch(i))
|
||||
auto const childBranch =
|
||||
(direction == BelowDirection::Last) ? (kBranchFactor - 1u - scanned) : scanned;
|
||||
|
||||
if (!inner->isEmptyBranch(childBranch))
|
||||
{
|
||||
node.adopt(descendThrow(inner.get(), i));
|
||||
node.adopt(descendThrow(inner.get(), childBranch));
|
||||
XRPL_ASSERT(!stack.empty(), "xrpl::SHAMap::belowHelper : non-empty stack");
|
||||
if (node->isLeaf())
|
||||
{
|
||||
@@ -466,32 +468,24 @@ SHAMap::belowHelper(
|
||||
}
|
||||
inner = intr_ptr::staticPointerCast<SHAMapInnerNode>(node);
|
||||
stack.emplace(inner, stack.top().second.getChildNodeID(branch));
|
||||
i = init; // descend and reset loop
|
||||
scanned = 0u; // descend and restart the scan on the new node
|
||||
}
|
||||
else
|
||||
{
|
||||
incr(i); // scan next branch
|
||||
++scanned; // scan next branch
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
SHAMapLeafNode*
|
||||
SHAMap::lastBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, int branch) const
|
||||
SHAMap::lastBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, unsigned int branch) const
|
||||
{
|
||||
auto init = kBranchFactor - 1;
|
||||
auto cmp = [](int i) { return i >= 0; };
|
||||
auto incr = [](int& i) { --i; };
|
||||
|
||||
return belowHelper(node, stack, branch, {init, cmp, incr});
|
||||
return belowHelper(node, stack, branch, BelowDirection::Last);
|
||||
}
|
||||
SHAMapLeafNode*
|
||||
SHAMap::firstBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, int branch) const
|
||||
SHAMap::firstBelow(SHAMapTreeNodePtr node, SharedPtrNodeStack& stack, unsigned int branch) const
|
||||
{
|
||||
auto init = 0;
|
||||
auto cmp = [](int i) { return i <= kBranchFactor; };
|
||||
auto incr = [](int& i) { ++i; };
|
||||
|
||||
return belowHelper(node, stack, branch, {init, cmp, incr});
|
||||
return belowHelper(node, stack, branch, BelowDirection::First);
|
||||
}
|
||||
static boost::intrusive_ptr<SHAMapItem const> const kNoItem;
|
||||
|
||||
@@ -504,7 +498,7 @@ SHAMap::onlyBelow(SHAMapTreeNode* node) const
|
||||
{
|
||||
SHAMapTreeNode* nextNode = nullptr;
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
for (int i = 0; i < kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (!inner->isEmptyBranch(i))
|
||||
{
|
||||
@@ -650,8 +644,9 @@ SHAMap::lowerBound(uint256 const& id) const
|
||||
else
|
||||
{
|
||||
auto inner = intr_ptr::staticPointerCast<SHAMapInnerNode>(node);
|
||||
for (int branch = selectBranch(nodeID, id) - 1; branch >= 0; --branch)
|
||||
for (auto branch = selectBranch(nodeID, id); branch > 0u;)
|
||||
{
|
||||
--branch;
|
||||
if (!inner->isEmptyBranch(branch))
|
||||
{
|
||||
node = descendThrow(*inner, branch);
|
||||
@@ -715,7 +710,7 @@ SHAMap::delItem(uint256 const& id)
|
||||
{
|
||||
// we may have made this a node with 1 or 0 children
|
||||
// And, if so, we need to remove this branch
|
||||
int const bc = node->getBranchCount();
|
||||
auto const bc = node->getBranchCount();
|
||||
if (bc == 0)
|
||||
{
|
||||
// no children below this branch
|
||||
@@ -730,7 +725,7 @@ SHAMap::delItem(uint256 const& id)
|
||||
|
||||
if (item)
|
||||
{
|
||||
for (int i = 0; i < kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (!node->isEmptyBranch(i))
|
||||
{
|
||||
@@ -786,7 +781,7 @@ SHAMap::addGiveItem(SHAMapNodeType type, boost::intrusive_ptr<SHAMapItem const>
|
||||
{
|
||||
// easy case, we end on an inner node
|
||||
auto inner = intr_ptr::staticPointerCast<SHAMapInnerNode>(node);
|
||||
int const branch = selectBranch(nodeID, tag);
|
||||
auto const branch = selectBranch(nodeID, tag);
|
||||
XRPL_ASSERT(
|
||||
inner->isEmptyBranch(branch), "xrpl::SHAMap::addGiveItem : inner branch is empty");
|
||||
inner->setChild(branch, makeTypedLeaf(type, std::move(item), cowid_));
|
||||
@@ -802,7 +797,7 @@ SHAMap::addGiveItem(SHAMapNodeType type, boost::intrusive_ptr<SHAMapItem const>
|
||||
|
||||
node = intr_ptr::makeShared<SHAMapInnerNode>(node->cowid());
|
||||
|
||||
unsigned int b1 = 0, b2 = 0;
|
||||
auto b1 = 0u, b2 = 0u;
|
||||
|
||||
while ((b1 = selectBranch(nodeID, tag)) == (b2 = selectBranch(nodeID, otherItem->key())))
|
||||
{
|
||||
@@ -1012,12 +1007,12 @@ SHAMap::walkSubTree(bool doWrite, NodeObjectType t)
|
||||
|
||||
// Stack of {parent,index,child} pointers representing
|
||||
// inner nodes we are in the process of flushing
|
||||
using StackEntry = std::pair<intr_ptr::SharedPtr<SHAMapInnerNode>, int>;
|
||||
using StackEntry = std::pair<intr_ptr::SharedPtr<SHAMapInnerNode>, unsigned int>;
|
||||
std::stack<StackEntry, std::vector<StackEntry>> stack;
|
||||
|
||||
node = preFlushNode(std::move(node));
|
||||
|
||||
int pos = 0;
|
||||
auto pos = 0u;
|
||||
|
||||
// We can't flush an inner node until we flush its children
|
||||
while (true)
|
||||
@@ -1032,7 +1027,7 @@ SHAMap::walkSubTree(bool doWrite, NodeObjectType t)
|
||||
{
|
||||
// No need to do I/O. If the node isn't linked,
|
||||
// it can't need to be flushed
|
||||
int const branch = pos;
|
||||
auto const branch = pos;
|
||||
auto child = node->getChild(pos++);
|
||||
|
||||
if (child && (child->cowid() != 0))
|
||||
@@ -1126,7 +1121,7 @@ SHAMap::dump(bool hash) const
|
||||
if (node->isInner())
|
||||
{
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
for (int i = 0; i < kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (!inner->isEmptyBranch(i))
|
||||
{
|
||||
|
||||
@@ -54,7 +54,7 @@ SHAMap::walkBranch(
|
||||
{
|
||||
// This is an inner node, add all non-empty branches
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if (!inner->isEmptyBranch(i))
|
||||
nodeStack.push({descendThrow(inner, i)});
|
||||
@@ -205,7 +205,7 @@ SHAMap::compare(SHAMap const& otherMap, Delta& differences, int maxCount) const
|
||||
{
|
||||
auto ours = safeDowncast<SHAMapInnerNode*>(ourNode);
|
||||
auto other = safeDowncast<SHAMapInnerNode*>(otherNode);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if (ours->getChildHash(i) != other->getChildHash(i))
|
||||
{
|
||||
@@ -257,7 +257,7 @@ SHAMap::walkMap(std::vector<SHAMapMissingNode>& missingNodes, int maxMissing) co
|
||||
intr_ptr::SharedPtr<SHAMapInnerNode> const node = std::move(nodeStack.top());
|
||||
nodeStack.pop();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if (!node->isEmptyBranch(i))
|
||||
{
|
||||
@@ -286,27 +286,29 @@ SHAMap::walkMapParallel(std::vector<SHAMapMissingNode>& missingNodes, int maxMis
|
||||
return false;
|
||||
|
||||
using StackEntry = intr_ptr::SharedPtr<SHAMapInnerNode>;
|
||||
std::array<SHAMapTreeNodePtr, 16> topChildren;
|
||||
std::array<SHAMapTreeNodePtr, SHAMapInnerNode::kBranchFactor> topChildren;
|
||||
{
|
||||
auto const& innerRoot = intr_ptr::staticPointerCast<SHAMapInnerNode>(root_);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if (!innerRoot->isEmptyBranch(i))
|
||||
topChildren[i] = descendNoStore(*innerRoot, i);
|
||||
}
|
||||
}
|
||||
std::vector<std::thread> workers;
|
||||
workers.reserve(16);
|
||||
workers.reserve(SHAMapInnerNode::kBranchFactor);
|
||||
std::vector<SHAMapMissingNode> exceptions;
|
||||
exceptions.reserve(16);
|
||||
exceptions.reserve(SHAMapInnerNode::kBranchFactor);
|
||||
|
||||
std::array<std::stack<StackEntry, std::vector<StackEntry>>, 16> nodeStacks;
|
||||
std::array<std::stack<StackEntry, std::vector<StackEntry>>, SHAMapInnerNode::kBranchFactor>
|
||||
nodeStacks;
|
||||
|
||||
// This mutex is used inside the worker threads to protect `missingNodes`
|
||||
// and `maxMissing` from race conditions
|
||||
std::mutex m;
|
||||
|
||||
for (int rootChildIndex = 0; rootChildIndex < 16; ++rootChildIndex)
|
||||
for (auto rootChildIndex = 0u; rootChildIndex < SHAMapInnerNode::kBranchFactor;
|
||||
++rootChildIndex)
|
||||
{
|
||||
auto const& child = topChildren[rootChildIndex];
|
||||
if (!child || !child->isInner())
|
||||
@@ -327,7 +329,7 @@ SHAMap::walkMapParallel(std::vector<SHAMapMissingNode>& missingNodes, int maxMis
|
||||
XRPL_ASSERT(node, "xrpl::SHAMap::walkMapParallel : non-null node");
|
||||
nodeStack.pop();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < SHAMapInnerNode::kBranchFactor; ++i)
|
||||
{
|
||||
if (node->isEmptyBranch(i))
|
||||
continue;
|
||||
|
||||
@@ -63,8 +63,8 @@ SHAMapInnerNode::resizeChildArrays(std::uint8_t toAllocate)
|
||||
hashesAndChildren_ = TaggedPointer(std::move(hashesAndChildren_), isBranch_, toAllocate);
|
||||
}
|
||||
|
||||
std::optional<int>
|
||||
SHAMapInnerNode::getChildIndex(int i) const
|
||||
std::optional<unsigned int>
|
||||
SHAMapInnerNode::getChildIndex(unsigned int i) const
|
||||
{
|
||||
return hashesAndChildren_.getChildIndex(isBranch_, i);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ SHAMapInnerNode::clone(std::uint32_t cowid) const
|
||||
|
||||
if (thisIsSparse)
|
||||
{
|
||||
int cloneChildIndex = 0;
|
||||
auto cloneChildIndex = 0u;
|
||||
iterNonEmptyChildIndexes([&](auto branchNum, auto indexNum) {
|
||||
cloneHashes[cloneChildIndex++] = thisHashes[indexNum];
|
||||
});
|
||||
@@ -105,7 +105,7 @@ SHAMapInnerNode::clone(std::uint32_t cowid) const
|
||||
|
||||
if (thisIsSparse)
|
||||
{
|
||||
int cloneChildIndex = 0;
|
||||
auto cloneChildIndex = 0u;
|
||||
iterNonEmptyChildIndexes([&](auto branchNum, auto indexNum) {
|
||||
cloneChildren[cloneChildIndex++] = thisChildren[indexNum];
|
||||
});
|
||||
@@ -133,12 +133,12 @@ SHAMapInnerNode::makeFullInner(Slice data, SHAMapHash const& hash, bool hashVali
|
||||
|
||||
auto hashes = ret->hashesAndChildren_.getHashes();
|
||||
|
||||
for (int i = 0; i < kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
hashes[i].asUInt256() = si.getBitString<256>();
|
||||
|
||||
if (hashes[i].isNonZero())
|
||||
ret->isBranch_ |= (1 << i);
|
||||
ret->isBranch_ |= (1u << i);
|
||||
}
|
||||
|
||||
ret->resizeChildArrays(ret->getBranchCount());
|
||||
@@ -182,7 +182,7 @@ SHAMapInnerNode::makeCompressedInner(Slice data)
|
||||
hashes[pos].asUInt256() = hash;
|
||||
|
||||
if (hashes[pos].isNonZero())
|
||||
ret->isBranch_ |= (1 << pos);
|
||||
ret->isBranch_ |= (1u << pos);
|
||||
}
|
||||
|
||||
ret->resizeChildArrays(ret->getBranchCount());
|
||||
@@ -267,20 +267,19 @@ SHAMapInnerNode::getString(SHAMapNodeID const& id) const
|
||||
|
||||
// We are modifying an inner node
|
||||
void
|
||||
SHAMapInnerNode::setChild(int m, SHAMapTreeNodePtr child)
|
||||
SHAMapInnerNode::setChild(unsigned int branch, SHAMapTreeNodePtr child)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(m >= 0) && (m < kBranchFactor), "xrpl::SHAMapInnerNode::setChild : valid branch input");
|
||||
XRPL_ASSERT(branch < kBranchFactor, "xrpl::SHAMapInnerNode::setChild : valid branch input");
|
||||
XRPL_ASSERT(cowid_, "xrpl::SHAMapInnerNode::setChild : nonzero cowid");
|
||||
XRPL_ASSERT(child.get() != this, "xrpl::SHAMapInnerNode::setChild : valid child input");
|
||||
|
||||
auto const dstIsBranch = [&] {
|
||||
if (child)
|
||||
{
|
||||
return isBranch_ | (1u << m);
|
||||
return isBranch_ | (1u << branch);
|
||||
}
|
||||
|
||||
return isBranch_ & ~(1u << m);
|
||||
return isBranch_ & ~(1u << branch);
|
||||
}();
|
||||
|
||||
auto const dstToAllocate = popcnt16(dstIsBranch);
|
||||
@@ -293,8 +292,8 @@ SHAMapInnerNode::setChild(int m, SHAMapTreeNodePtr child)
|
||||
|
||||
if (child)
|
||||
{
|
||||
auto const childIndex =
|
||||
*getChildIndex(m); // NOLINT(bugprone-unchecked-optional-access) isBranch_ set above
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) isBranch_ set above
|
||||
auto const childIndex = *getChildIndex(branch);
|
||||
auto [_, hashes, children] = hashesAndChildren_.getHashesAndChildren();
|
||||
hashes[childIndex].zero();
|
||||
children[childIndex] = std::move(child);
|
||||
@@ -309,25 +308,24 @@ SHAMapInnerNode::setChild(int m, SHAMapTreeNodePtr child)
|
||||
|
||||
// finished modifying, now make shareable
|
||||
void
|
||||
SHAMapInnerNode::shareChild(int m, SHAMapTreeNodePtr const& child)
|
||||
SHAMapInnerNode::shareChild(unsigned int branch, SHAMapTreeNodePtr const& child)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(m >= 0) && (m < kBranchFactor), "xrpl::SHAMapInnerNode::shareChild : valid branch input");
|
||||
XRPL_ASSERT(branch < kBranchFactor, "xrpl::SHAMapInnerNode::shareChild : valid branch input");
|
||||
XRPL_ASSERT(cowid_, "xrpl::SHAMapInnerNode::shareChild : nonzero cowid");
|
||||
XRPL_ASSERT(child, "xrpl::SHAMapInnerNode::shareChild : non-null child input");
|
||||
XRPL_ASSERT(child.get() != this, "xrpl::SHAMapInnerNode::shareChild : valid child input");
|
||||
|
||||
XRPL_ASSERT(!isEmptyBranch(m), "xrpl::SHAMapInnerNode::shareChild : non-empty branch input");
|
||||
XRPL_ASSERT(
|
||||
!isEmptyBranch(branch), "xrpl::SHAMapInnerNode::shareChild : non-empty branch input");
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) assert above
|
||||
hashesAndChildren_.getChildren()[*getChildIndex(m)] = child;
|
||||
hashesAndChildren_.getChildren()[*getChildIndex(branch)] = child;
|
||||
}
|
||||
|
||||
SHAMapTreeNode*
|
||||
SHAMapInnerNode::getChildPointer(int branch)
|
||||
SHAMapInnerNode::getChildPointer(unsigned int branch)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
branch >= 0 && branch < kBranchFactor,
|
||||
"xrpl::SHAMapInnerNode::getChildPointer : valid branch input");
|
||||
branch < kBranchFactor, "xrpl::SHAMapInnerNode::getChildPointer : valid branch input");
|
||||
XRPL_ASSERT(
|
||||
!isEmptyBranch(branch), "xrpl::SHAMapInnerNode::getChildPointer : non-empty branch input");
|
||||
|
||||
@@ -340,11 +338,9 @@ SHAMapInnerNode::getChildPointer(int branch)
|
||||
}
|
||||
|
||||
SHAMapTreeNodePtr
|
||||
SHAMapInnerNode::getChild(int branch)
|
||||
SHAMapInnerNode::getChild(unsigned int branch)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
branch >= 0 && branch < kBranchFactor,
|
||||
"xrpl::SHAMapInnerNode::getChild : valid branch input");
|
||||
XRPL_ASSERT(branch < kBranchFactor, "xrpl::SHAMapInnerNode::getChild : valid branch input");
|
||||
XRPL_ASSERT(!isEmptyBranch(branch), "xrpl::SHAMapInnerNode::getChild : non-empty branch input");
|
||||
|
||||
auto const index =
|
||||
@@ -356,23 +352,20 @@ SHAMapInnerNode::getChild(int branch)
|
||||
}
|
||||
|
||||
SHAMapHash const&
|
||||
SHAMapInnerNode::getChildHash(int m) const
|
||||
SHAMapInnerNode::getChildHash(unsigned int branch) const
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(m >= 0) && (m < kBranchFactor),
|
||||
"xrpl::SHAMapInnerNode::getChildHash : valid branch input");
|
||||
if (auto const i = getChildIndex(m))
|
||||
XRPL_ASSERT(branch < kBranchFactor, "xrpl::SHAMapInnerNode::getChildHash : valid branch input");
|
||||
if (auto const i = getChildIndex(branch))
|
||||
return hashesAndChildren_.getHashes()[*i];
|
||||
|
||||
return kZeroShaMapHash;
|
||||
}
|
||||
|
||||
SHAMapTreeNodePtr
|
||||
SHAMapInnerNode::canonicalizeChild(int branch, SHAMapTreeNodePtr node)
|
||||
SHAMapInnerNode::canonicalizeChild(unsigned int branch, SHAMapTreeNodePtr node)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
branch >= 0 && branch < kBranchFactor,
|
||||
"xrpl::SHAMapInnerNode::canonicalizeChild : valid branch input");
|
||||
branch < kBranchFactor, "xrpl::SHAMapInnerNode::canonicalizeChild : valid branch input");
|
||||
XRPL_ASSERT(node != nullptr, "xrpl::SHAMapInnerNode::canonicalizeChild : valid node input");
|
||||
XRPL_ASSERT(
|
||||
!isEmptyBranch(branch),
|
||||
@@ -410,7 +403,7 @@ SHAMapInnerNode::invariants(bool isRoot) const
|
||||
if (numAllocated != kBranchFactor)
|
||||
{
|
||||
auto const branchCount = getBranchCount();
|
||||
for (int i = 0; i < branchCount; ++i)
|
||||
for (auto i = 0u; i < branchCount; ++i)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
hashes[i].isNonZero(),
|
||||
@@ -422,12 +415,12 @@ SHAMapInnerNode::invariants(bool isRoot) const
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < kBranchFactor; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (hashes[i].isNonZero())
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(isBranch_ & (1 << i)),
|
||||
(isBranch_ & (1u << i)),
|
||||
"xrpl::SHAMapInnerNode::invariants : valid branch when "
|
||||
"nonzero hash");
|
||||
if (children[i] != nullptr)
|
||||
@@ -437,7 +430,7 @@ SHAMapInnerNode::invariants(bool isRoot) const
|
||||
else
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(isBranch_ & (1 << i)) == 0,
|
||||
(isBranch_ & (1u << i)) == 0u,
|
||||
"xrpl::SHAMapInnerNode::invariants : valid branch when "
|
||||
"zero hash");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace xrpl {
|
||||
static uint256 const&
|
||||
depthMask(unsigned int depth)
|
||||
{
|
||||
static constexpr auto kMaskSize = 65;
|
||||
static constexpr auto kMaskSize = SHAMap::kLeafDepth + 1;
|
||||
|
||||
struct MasksT
|
||||
{
|
||||
@@ -25,7 +25,7 @@ depthMask(unsigned int depth)
|
||||
MasksT()
|
||||
{
|
||||
uint256 selector;
|
||||
for (int i = 0; i < kMaskSize - 1; i += 2)
|
||||
for (auto i = 0u; i < kMaskSize - 1; i += 2)
|
||||
{
|
||||
entry[i] = selector;
|
||||
*(selector.begin() + (i / 2)) = 0xF0;
|
||||
@@ -60,10 +60,10 @@ SHAMapNodeID::getRawString() const
|
||||
}
|
||||
|
||||
SHAMapNodeID
|
||||
SHAMapNodeID::getChildNodeID(unsigned int m) const
|
||||
SHAMapNodeID::getChildNodeID(unsigned int branch) const
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
m < SHAMap::kBranchFactor, "xrpl::SHAMapNodeID::getChildNodeID : valid branch input");
|
||||
branch < SHAMap::kBranchFactor, "xrpl::SHAMapNodeID::getChildNodeID : valid branch input");
|
||||
|
||||
// A SHAMap has exactly 65 levels, so nodes must not exceed that
|
||||
// depth; if they do, this breaks the invariant of never allowing
|
||||
@@ -83,7 +83,7 @@ SHAMapNodeID::getChildNodeID(unsigned int m) const
|
||||
Throw<std::logic_error>("Incorrect mask for " + to_string(*this));
|
||||
|
||||
SHAMapNodeID node{depth_ + 1, id_};
|
||||
node.id_.begin()[depth_ / 2] |= ((depth_ & 1) != 0u) ? m : (m << 4);
|
||||
node.id_.begin()[depth_ / 2] |= ((depth_ & 1) != 0u) ? branch : (branch << 4);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -127,10 +127,9 @@ selectBranch(SHAMapNodeID const& id, uint256 const& hash)
|
||||
}
|
||||
|
||||
SHAMapNodeID
|
||||
SHAMapNodeID::createID(int depth, uint256 const& key)
|
||||
SHAMapNodeID::createID(unsigned int depth, uint256 const& key)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
depth >= 0 && depth <= SHAMap::kLeafDepth, "xrpl::SHAMapNodeID::createID : valid depth");
|
||||
XRPL_ASSERT(depth <= SHAMap::kLeafDepth, "xrpl::SHAMapNodeID::createID : valid depth");
|
||||
return SHAMapNodeID(depth, key & depthMask(depth));
|
||||
}
|
||||
|
||||
|
||||
@@ -54,15 +54,15 @@ SHAMap::visitNodes(std::function<bool(SHAMapTreeNode&)> const& function) const
|
||||
if (!root_->isInner())
|
||||
return;
|
||||
|
||||
using StackEntry = std::pair<int, intr_ptr::SharedPtr<SHAMapInnerNode>>;
|
||||
using StackEntry = std::pair<unsigned int, intr_ptr::SharedPtr<SHAMapInnerNode>>;
|
||||
std::stack<StackEntry, std::vector<StackEntry>> stack;
|
||||
|
||||
auto node = intr_ptr::staticPointerCast<SHAMapInnerNode>(root_);
|
||||
int pos = 0;
|
||||
auto pos = 0u;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (pos < 16)
|
||||
while (pos < kBranchFactor)
|
||||
{
|
||||
if (!node->isEmptyBranch(pos))
|
||||
{
|
||||
@@ -77,10 +77,10 @@ SHAMap::visitNodes(std::function<bool(SHAMapTreeNode&)> const& function) const
|
||||
else
|
||||
{
|
||||
// If there are no more children, don't push this node
|
||||
while ((pos != 15) && (node->isEmptyBranch(pos + 1)))
|
||||
while ((pos != kBranchFactor - 1u) && (node->isEmptyBranch(pos + 1)))
|
||||
++pos;
|
||||
|
||||
if (pos != 15)
|
||||
if (pos != kBranchFactor - 1u)
|
||||
{
|
||||
// save next position to resume at
|
||||
stack.emplace(pos + 1, std::move(node));
|
||||
@@ -144,7 +144,7 @@ SHAMap::visitDifferences(
|
||||
return;
|
||||
|
||||
// 2) push non-matching child inner nodes
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (!node->isEmptyBranch(i))
|
||||
{
|
||||
@@ -176,13 +176,13 @@ SHAMap::gmnProcessNodes(MissingNodes& mn, MissingNodes::StackEntry& se)
|
||||
{
|
||||
SHAMapInnerNode*& node = std::get<0>(se);
|
||||
SHAMapNodeID& nodeID = std::get<1>(se);
|
||||
int& firstChild = std::get<2>(se);
|
||||
int& currentChild = std::get<3>(se);
|
||||
auto& firstChild = std::get<2>(se);
|
||||
auto& currentChild = std::get<3>(se);
|
||||
bool& fullBelow = std::get<4>(se);
|
||||
|
||||
while (currentChild < 16)
|
||||
while (currentChild < kBranchFactor)
|
||||
{
|
||||
int const branch = (firstChild + currentChild++) % 16;
|
||||
auto const branch = (firstChild + currentChild++) % kBranchFactor;
|
||||
if (node->isEmptyBranch(branch))
|
||||
continue;
|
||||
|
||||
@@ -262,7 +262,7 @@ SHAMap::gmnProcessDeferredReads(MissingNodes& mn)
|
||||
int complete = 0;
|
||||
while (complete != mn.deferred)
|
||||
{
|
||||
std::tuple<SHAMapInnerNode*, SHAMapNodeID, int, SHAMapTreeNodePtr> deferredNode;
|
||||
MissingNodes::DeferredNode deferredNode;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock{mn.deferLock};
|
||||
|
||||
@@ -423,7 +423,7 @@ SHAMap::getNodeFat(
|
||||
|
||||
while ((node != nullptr) && node->isInner() && (nodeID.getDepth() < wanted.getDepth()))
|
||||
{
|
||||
int const branch = selectBranch(nodeID, wanted.getNodeID());
|
||||
auto const branch = selectBranch(nodeID, wanted.getNodeID());
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
if (inner->isEmptyBranch(branch))
|
||||
return false;
|
||||
@@ -444,7 +444,7 @@ SHAMap::getNodeFat(
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stack<std::tuple<SHAMapTreeNode*, SHAMapNodeID, int>> stack;
|
||||
std::stack<std::tuple<SHAMapTreeNode*, SHAMapNodeID, std::uint32_t>> stack;
|
||||
stack.emplace(node, nodeID, depth);
|
||||
|
||||
Serializer s(8192);
|
||||
@@ -464,12 +464,12 @@ SHAMap::getNodeFat(
|
||||
// We descend inner nodes with only a single child
|
||||
// without decrementing the depth
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
int const bc = inner->getBranchCount();
|
||||
auto const bc = inner->getBranchCount();
|
||||
|
||||
if ((depth > 0) || (bc == 1))
|
||||
{
|
||||
// We need to process this node's children
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (!inner->isEmptyBranch(i))
|
||||
{
|
||||
@@ -575,8 +575,7 @@ SHAMap::addKnownNode(
|
||||
!safeDowncast<SHAMapInnerNode*>(currNode)->isFullBelow(generation) &&
|
||||
(currNodeID.getDepth() < nodeID.getDepth()))
|
||||
{
|
||||
int const branch = selectBranch(currNodeID, nodeID.getNodeID());
|
||||
XRPL_ASSERT(branch >= 0, "xrpl::SHAMap::addKnownNode : valid branch");
|
||||
auto const branch = selectBranch(currNodeID, nodeID.getNodeID());
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(currNode);
|
||||
if (inner->isEmptyBranch(branch))
|
||||
{
|
||||
@@ -686,7 +685,7 @@ SHAMap::deepCompare(SHAMap& other) const
|
||||
return false;
|
||||
auto nodeInner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
auto otherInner = safeDowncast<SHAMapInnerNode*>(otherNode);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (auto i = 0u; i < kBranchFactor; ++i)
|
||||
{
|
||||
if (nodeInner->isEmptyBranch(i))
|
||||
{
|
||||
@@ -725,7 +724,7 @@ SHAMap::hasInnerNode(SHAMapNodeID const& targetNodeID, SHAMapHash const& targetN
|
||||
|
||||
while (node->isInner() && (nodeID.getDepth() < targetNodeID.getDepth()))
|
||||
{
|
||||
int const branch = selectBranch(nodeID, targetNodeID.getNodeID());
|
||||
auto const branch = selectBranch(nodeID, targetNodeID.getNodeID());
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
if (inner->isEmptyBranch(branch))
|
||||
return false;
|
||||
@@ -751,7 +750,20 @@ SHAMap::hasLeafNode(uint256 const& tag, SHAMapHash const& targetNodeHash) const
|
||||
|
||||
do
|
||||
{
|
||||
int const branch = selectBranch(nodeID, tag);
|
||||
// An inner node is only reachable here at a depth below kLeafDepth in a well-formed map,
|
||||
// where the loop always finds a leaf first. A malformed map could still have an inner
|
||||
// node claiming kLeafDepth, and getChildNodeID below throws in that case: reject rather
|
||||
// than let the throw escape uncaught. Not reachable through any public entry point,
|
||||
// since addKnownNode already marks such a map invalid, so no test can cover this.
|
||||
if (nodeID.getDepth() >= kLeafDepth)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("xrpl::SHAMap::hasLeafNode : inner node at leaf depth");
|
||||
return false;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const branch = selectBranch(nodeID, tag);
|
||||
auto inner = safeDowncast<SHAMapInnerNode*>(node);
|
||||
if (inner->isEmptyBranch(branch))
|
||||
return false; // Dead end, node must not be here
|
||||
@@ -803,7 +815,7 @@ SHAMap::getProofPath(uint256 const& key) const
|
||||
bool
|
||||
SHAMap::verifyProofPath(uint256 const& rootHash, uint256 const& key, std::vector<Blob> const& path)
|
||||
{
|
||||
if (path.empty() || path.size() > 65)
|
||||
if (path.empty() || path.size() > kLeafDepth + 1u)
|
||||
return false;
|
||||
|
||||
SHAMapHash hash{rootHash};
|
||||
@@ -819,10 +831,10 @@ SHAMap::verifyProofPath(uint256 const& rootHash, uint256 const& key, std::vector
|
||||
if (node->getHash() != hash)
|
||||
return false;
|
||||
|
||||
auto depth = std::distance(path.rbegin(), rit);
|
||||
auto const depth = std::distance(path.rbegin(), rit);
|
||||
if (node->isInner())
|
||||
{
|
||||
auto nodeId = SHAMapNodeID::createID(depth, key);
|
||||
auto nodeId = SHAMapNodeID::createID(static_cast<unsigned int>(depth), key);
|
||||
hash = safeDowncast<SHAMapInnerNode*>(node.get())
|
||||
->getChildHash(selectBranch(nodeId, key));
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ getSHAMapNodeID(protocol::TMLedgerNode const& ledgerNode, SHAMapTreeNode const&
|
||||
if (treeNode.isLeaf())
|
||||
{
|
||||
auto const key = leafKey(treeNode);
|
||||
auto const expectedID = SHAMapNodeID::createID(static_cast<int>(nodeID->getDepth()), key);
|
||||
auto const expectedID = SHAMapNodeID::createID(nodeID->getDepth(), key);
|
||||
SOMETIMES(
|
||||
nodeID->getNodeID() != expectedID.getNodeID(),
|
||||
"xrpl::getSHAMapNodeID : legacy leaf ID inconsistent with key");
|
||||
|
||||
Reference in New Issue
Block a user