25 using std::unique_ptr;
31 const size_t MIN_ALLOC_SIZE = 2000;
32 const size_t MAX_ALLOC_SIZE = 8000;
33 const size_t MAX_PACK_COPY = 4096;
38 void appendToChain(unique_ptr<IOBuf>& dst, unique_ptr<IOBuf>&& src,
bool pack) {
42 IOBuf* tail = dst->prev();
47 size_t copyRemaining = MAX_PACK_COPY;
49 while (src && (n = src->length()) < copyRemaining &&
50 n < tail->tailroom() && n > 0) {
51 memcpy(tail->writableTail(), src->data(), n);
68 : options_(options), cachePtr_(&localCache_) {
78 other.clearWritableRangeCache();
83 localCache_.cachedRange = other.localCache_.cachedRange;
84 localCache_.attached =
true;
86 other.chainLength_ = 0;
87 other.tailStart_ =
nullptr;
88 other.localCache_.cachedRange = {
nullptr,
nullptr};
104 other.chainLength_ = 0;
105 other.tailStart_ =
nullptr;
106 other.localCache_.cachedRange = {
nullptr,
nullptr};
115 return std::make_pair(
head_->writableBuffer(),
head_->headroom());
117 return std::make_pair(
nullptr, 0);
134 auto hroom =
head_->headroom();
135 if (!
head_ || hroom < n) {
136 throw std::overflow_error(
"Not enough room to prepend");
138 memcpy(
head_->writableBuffer() + hroom - n, buf, n);
174 auto src =
static_cast<const uint8_t*
>(buf);
176 if ((
head_ ==
nullptr) ||
head_->prev()->isSharedOne() ||
177 (
head_->prev()->tailroom() == 0)) {
197 std::size_t blockSize) {
198 auto src =
static_cast<const uint8_t*
>(buf);
200 size_t n =
std::min(len,
size_t(blockSize));
209 std::size_t newAllocationSize,
225 unique_ptr<IOBuf> result;
227 if (
head_ ==
nullptr) {
228 if (throwOnUnderflow) {
229 throw std::underflow_error(
230 "Attempt to remove more bytes than are present in IOBufQueue");
234 }
else if (
head_->length() <= n) {
235 n -=
head_->length();
237 unique_ptr<IOBuf> remainder =
head_->pop();
241 unique_ptr<IOBuf> clone =
head_->cloneOne();
242 clone->trimEnd(clone->length() - n);
243 appendToChain(result,
std::move(clone),
false);
257 if (trimmed != amount) {
258 throw std::underflow_error(
259 "Attempt to trim more bytes than are present in IOBufQueue");
265 auto original = amount;
270 if (
head_->length() > amount) {
271 head_->trimStart(amount);
276 amount -=
head_->length();
280 return original - amount;
285 if (trimmed != amount) {
286 throw std::underflow_error(
287 "Attempt to trim more bytes than are present in IOBufQueue");
293 auto original = amount;
298 if (
head_->prev()->length() > amount) {
299 head_->prev()->trimEnd(amount);
304 amount -=
head_->prev()->length();
307 if (
head_->isChained()) {
308 head_->prev()->unlink();
313 return original - amount;
336 }
while (buf !=
head_.get());
346 :
head_->computeChainDataLength() +
348 out.reserve(out.size() + len);
351 out.append(reinterpret_cast<const char*>(
range.data()),
range.size());
363 if (
head_ !=
nullptr) {
364 head_->gather(maxLength);
WritableRangeCacheData * cachePtr_
std::unique_ptr< folly::IOBuf > split(size_t n)
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
std::pair< void *, std::size_t > preallocateSlow(std::size_t min, std::size_t newAllocationSize, std::size_t max)
void prepend(const void *buf, std::size_t n)
static std::unique_ptr< IOBuf > create(std::size_t capacity)
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
constexpr detail::Map< Move > move
void clearWritableRangeCache()
void markPrepended(std::size_t n)
—— Concurrent Priority Queue Implementation ——
void appendToString(std::string &out) const
requires E e noexcept(noexcept(s.error(std::move(e))))
void * writableTail() const
std::size_t tailroom() const
size_t trimStartAtMost(size_t amount)
IOBufQueue(const Options &options=Options())
std::unique_ptr< IOBuf > pop()
WritableRangeCacheData localCache_
std::pair< void *, std::size_t > headroom()
GuardImpl guard(ErrorHandler &&handler)
void wrapBuffer(const void *buf, size_t len, std::size_t blockSize=(1U<< 31))
constexpr Range< Iter > range(Iter first, Iter last)
std::unique_ptr< folly::IOBuf > head_
size_t trimEndAtMost(size_t amount)
IOBufQueue & operator=(IOBufQueue &&)
void trimStart(size_t amount)
std::pair< uint8_t *, uint8_t * > cachedRange
void trimEnd(size_t amount)
void gather(std::size_t maxLength)
void append(std::size_t amount)
std::unique_ptr< folly::IOBuf > pop_front()