X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fio%2FIOBufQueue.h;h=c801920d34f793cd9e60608af254207652657564;hp=7046dc00d5f3e9c50200dc8c5dcbdbb12961c5b2;hb=7ebe7c2a249de44209e8bcc453e1a70bafd4ed19;hpb=bae9c76c2a7f76355d2d31d8fb98718314bb6a82 diff --git a/folly/io/IOBufQueue.h b/folly/io/IOBufQueue.h index 7046dc00..c801920d 100644 --- a/folly/io/IOBufQueue.h +++ b/folly/io/IOBufQueue.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,9 @@ * limitations under the License. */ -#ifndef FOLLY_IO_IOBUF_QUEUE_H -#define FOLLY_IO_IOBUF_QUEUE_H +#pragma once -#include "folly/io/IOBuf.h" +#include #include #include @@ -54,18 +53,18 @@ class IOBufQueue { /** * Return a space to prepend bytes and the amount of headroom available. */ - std::pair headroom(); + std::pair headroom(); /** * Indicate that n bytes from the headroom have been used. */ - void markPrepended(uint32_t n); + void markPrepended(uint64_t n); /** * Prepend an existing range; throws std::overflow_error if not enough * room. */ - void prepend(const void* buf, uint32_t n); + void prepend(const void* buf, uint64_t n); /** * Add a buffer or buffer chain to the end of this queue. The @@ -98,8 +97,8 @@ class IOBufQueue { * Copy a string to the end of this queue. * The caller retains ownership of the source data. */ - void append(const std::string& buf) { - append(buf.data(), buf.length()); + void append(StringPiece sp) { + append(sp.data(), sp.size()); } /** @@ -115,7 +114,7 @@ class IOBufQueue { * Importantly, this method may be used to wrap buffers larger than 4GB. */ void wrapBuffer(const void* buf, size_t len, - uint32_t blockSize=(1U << 31)); // default block size: 2GB + uint64_t blockSize=(1U << 31)); // default block size: 2GB /** * Obtain a writable block of contiguous bytes at the end of this @@ -137,9 +136,9 @@ class IOBufQueue { * callback, tell the application how much of the buffer they've * filled with data. */ - std::pair preallocate( - uint32_t min, uint32_t newAllocationSize, - uint32_t max = std::numeric_limits::max()) { + std::pair preallocate( + uint64_t min, uint64_t newAllocationSize, + uint64_t max = std::numeric_limits::max()) { auto buf = tailBuf(); if (LIKELY(buf && buf->tailroom() >= min)) { return std::make_pair(buf->writableTail(), @@ -159,7 +158,7 @@ class IOBufQueue { * invoke any other non-const methods on this IOBufQueue between * the call to preallocate and the call to postallocate(). */ - void postallocate(uint32_t n) { + void postallocate(uint64_t n) { head_->prev()->append(n); chainLength_ += n; } @@ -168,7 +167,7 @@ class IOBufQueue { * Obtain a writable block of n contiguous bytes, allocating more space * if necessary, and mark it as used. The caller can fill it later. */ - void* allocate(uint32_t n) { + void* allocate(uint64_t n) { void* p = preallocate(n, n).first; postallocate(n); return p; @@ -196,7 +195,17 @@ class IOBufQueue { * @throws std::underflow_error if n exceeds the number of bytes * in the queue. */ - std::unique_ptr split(size_t n); + std::unique_ptr split(size_t n) { + return split(n, true); + } + + /** + * Similar to split, but will return the entire queue instead of throwing + * if n exceeds the number of bytes in the queue. + */ + std::unique_ptr splitAtMost(size_t n) { + return split(n, false); + } /** * Similar to IOBuf::trimStart, but works on the whole queue. Will @@ -204,12 +213,24 @@ class IOBufQueue { */ void trimStart(size_t amount); + /** + * Similar to trimStart, but will trim at most amount bytes and returns + * the number of bytes trimmed. + */ + size_t trimStartAtMost(size_t amount); + /** * Similar to IOBuf::trimEnd, but works on the whole queue. Will * pop off buffers that have been completely trimmed. */ void trimEnd(size_t amount); + /** + * Similar to trimEnd, but will trim at most amount bytes and returns + * the number of bytes trimmed. + */ + size_t trimEndAtMost(size_t amount); + /** * Transfer ownership of the queue's entire IOBuf chain to the caller. */ @@ -261,18 +282,32 @@ class IOBufQueue { */ void clear(); + /** + * Append the queue to a std::string. Non-destructive. + */ + void appendToString(std::string& out) const; + + /** + * Calls IOBuf::gather() on the head of the queue, if it exists. + */ + void gather(uint64_t maxLength); + /** Movable */ - IOBufQueue(IOBufQueue&&); + IOBufQueue(IOBufQueue&&) noexcept; IOBufQueue& operator=(IOBufQueue&&); private: IOBuf* tailBuf() const { - if (UNLIKELY(!head_)) return nullptr; + if (UNLIKELY(!head_)) { + return nullptr; + } IOBuf* buf = head_->prev(); return LIKELY(!buf->isSharedOne()) ? buf : nullptr; } - std::pair preallocateSlow( - uint32_t min, uint32_t newAllocationSize, uint32_t max); + std::pair preallocateSlow( + uint64_t min, uint64_t newAllocationSize, uint64_t max); + + std::unique_ptr split(size_t n, bool throwOnUnderflow); static const size_t kChainLengthNotCached = (size_t)-1; /** Not copyable */ @@ -289,6 +324,4 @@ class IOBufQueue { std::unique_ptr head_; }; -} // folly - -#endif // FOLLY_IO_IOBUF_QUEUE_H +} // namespace folly