Commit 345652aa authored by Philip Pronin's avatar Philip Pronin Committed by Facebook GitHub Bot

don't clone headroom and tailroom when unsharing non-managed input

Summary:
`clone()` preserves headroom and tailroom, so what is happening right
now when deserializing from non-managed buffer (such as wrapped range), is that
every lazy field would result in allocation equivalent in size to the input
buffer!

Apply that to a container and that becomes a combinatorial explosion.

(Note: this ignores all push blocking failures!)

Reviewed By: ot

Differential Revision: D32942233

fbshipit-source-id: b81d8389178b27068dce85b414883d75b1f50ca3
parent 5c8fc1b6
......@@ -784,9 +784,19 @@ IOBuf IOBuf::cloneCoalescedAsValue() const {
IOBuf IOBuf::cloneCoalescedAsValueWithHeadroomTailroom(
std::size_t newHeadroom, std::size_t newTailroom) const {
if (!isChained() && newHeadroom <= headroom() && newTailroom <= tailroom()) {
if (isChained() || newHeadroom != headroom()) {
// Fall through to slow code path.
} else if (newTailroom == tailroom()) {
return cloneOneAsValue();
} else if (newTailroom < tailroom()) {
const std::size_t newCapacity =
goodExtBufferSize(length_ + newHeadroom + newTailroom) -
sizeof(SharedInfo);
if (tailroom() <= newCapacity - newHeadroom - length_) {
return cloneOneAsValue();
}
}
// Coalesce into newBuf
const std::size_t newLength = computeChainDataLength();
const std::size_t newCapacity = newLength + newHeadroom + newTailroom;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment