mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-09 19:56:46 +00:00
Use node-specific size for serializer
This commit is contained in:
@@ -45,6 +45,12 @@ public:
|
||||
hash_ = SHAMapHash{sha512Half(HashPrefix::LeafNode, item_->slice(), item_->key())};
|
||||
}
|
||||
|
||||
std::size_t
|
||||
sizeForWire() const final
|
||||
{
|
||||
return item_->size() + uint256::kBytes + sizeof(std::uint8_t);
|
||||
}
|
||||
|
||||
void
|
||||
serializeForWire(Serializer& s) const final
|
||||
{
|
||||
|
||||
@@ -17,6 +17,12 @@ public:
|
||||
/** Each inner node has 16 children (the 'radix tree' part of the map) */
|
||||
static constexpr unsigned int kBranchFactor = 16;
|
||||
|
||||
/** Branch count below which compressed wire format is used instead of full.
|
||||
Compressed format encodes only populated branches, costing 33 bytes each
|
||||
plus a 1-byte type tag. Full format always emits all 16 hashes (513
|
||||
bytes). At this threshold, compressed is still smaller than full. */
|
||||
static constexpr unsigned int kCompressedThreshold = 12;
|
||||
|
||||
private:
|
||||
/** Opaque type that contains the `hashes` array (array of type
|
||||
`SHAMapHash`) and the `children` array (array of type
|
||||
@@ -149,6 +155,9 @@ public:
|
||||
void
|
||||
updateHashDeep();
|
||||
|
||||
std::size_t
|
||||
sizeForWire() const override;
|
||||
|
||||
void
|
||||
serializeForWire(Serializer&) const override;
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
sizeForWire() const override = 0;
|
||||
|
||||
void
|
||||
invariants(bool isRoot = false) const final;
|
||||
|
||||
|
||||
@@ -142,6 +142,10 @@ public:
|
||||
virtual bool
|
||||
isInner() const = 0;
|
||||
|
||||
/** Returns the exact number of bytes that serializeForWire will emit. */
|
||||
virtual std::size_t
|
||||
sizeForWire() const = 0;
|
||||
|
||||
/** Serialize the node in a format appropriate for sending over the wire */
|
||||
virtual void
|
||||
serializeForWire(Serializer&) const = 0;
|
||||
|
||||
@@ -44,6 +44,12 @@ public:
|
||||
hash_ = SHAMapHash{sha512Half(HashPrefix::TransactionId, item_->slice())};
|
||||
}
|
||||
|
||||
std::size_t
|
||||
sizeForWire() const final
|
||||
{
|
||||
return item_->size() + sizeof(std::uint8_t);
|
||||
}
|
||||
|
||||
void
|
||||
serializeForWire(Serializer& s) const final
|
||||
{
|
||||
|
||||
@@ -45,6 +45,12 @@ public:
|
||||
hash_ = SHAMapHash{sha512Half(HashPrefix::TxNode, item_->slice(), item_->key())};
|
||||
}
|
||||
|
||||
std::size_t
|
||||
sizeForWire() const final
|
||||
{
|
||||
return item_->size() + uint256::kBytes + sizeof(std::uint8_t);
|
||||
}
|
||||
|
||||
void
|
||||
serializeForWire(Serializer& s) const final
|
||||
{
|
||||
|
||||
@@ -219,13 +219,22 @@ SHAMapInnerNode::updateHashDeep()
|
||||
updateHash();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
SHAMapInnerNode::sizeForWire() const
|
||||
{
|
||||
auto const n = getBranchCount();
|
||||
if (n < kCompressedThreshold)
|
||||
return n * (uint256::kBytes + sizeof(std::uint8_t)) + sizeof(std::uint8_t);
|
||||
return kBranchFactor * uint256::kBytes + sizeof(std::uint8_t);
|
||||
}
|
||||
|
||||
void
|
||||
SHAMapInnerNode::serializeForWire(Serializer& s) const
|
||||
{
|
||||
XRPL_ASSERT(!isEmpty(), "xrpl::SHAMapInnerNode::serializeForWire : is non-empty");
|
||||
|
||||
// If the node is sparse, then only send non-empty branches:
|
||||
if (getBranchCount() < 12)
|
||||
if (getBranchCount() < kCompressedThreshold)
|
||||
{
|
||||
// compressed node
|
||||
auto hashes = hashesAndChildren_.getHashes();
|
||||
|
||||
@@ -454,9 +454,7 @@ SHAMap::getNodeFat(
|
||||
std::tie(node, nodeID, depth) = stack.top();
|
||||
stack.pop();
|
||||
|
||||
// Use a fresh Serializer per node and move its buffer into `data` rather than copying it
|
||||
// via Serializer::getData(): the move is O(1) whereas the copy was O(node size).
|
||||
Serializer s;
|
||||
Serializer s(node->sizeForWire());
|
||||
node->serializeForWire(s);
|
||||
data.emplace_back(nodeID, std::move(s.modData()));
|
||||
|
||||
@@ -486,7 +484,7 @@ SHAMap::getNodeFat(
|
||||
else if (childNode->isInner() || fatLeaves)
|
||||
{
|
||||
// Just include this node
|
||||
Serializer cs;
|
||||
Serializer cs(childNode->sizeForWire());
|
||||
childNode->serializeForWire(cs);
|
||||
data.emplace_back(childID, std::move(cs.modData()));
|
||||
}
|
||||
@@ -793,7 +791,7 @@ SHAMap::getProofPath(uint256 const& key) const
|
||||
path.reserve(stack.size());
|
||||
while (!stack.empty())
|
||||
{
|
||||
Serializer s;
|
||||
Serializer s(stack.top().first->sizeForWire());
|
||||
stack.top().first->serializeForWire(s);
|
||||
path.emplace_back(std::move(s.modData()));
|
||||
stack.pop();
|
||||
|
||||
Reference in New Issue
Block a user