Add CHECK for out-of-range minRequests
[folly.git] / folly / experimental / io / IOBufQueue.h
index 7c25c62157eaa999e264143b5b25d16234c1ca4d..cca5f98539dd3f87fc86da3c694e477c291e88d4 100644 (file)
@@ -28,6 +28,9 @@ namespace folly {
  * An IOBufQueue encapsulates a chain of IOBufs and provides
  * convenience functions to append data to the back of the chain
  * and remove data from the front.
+ *
+ * You may also prepend data into the headroom of the first buffer in the
+ * chain, if any.
  */
 class IOBufQueue {
  public:
@@ -36,8 +39,34 @@ class IOBufQueue {
     bool cacheChainLength;
   };
 
+  /**
+   * Commonly used Options, currently the only possible value other than
+   * the default.
+   */
+  static Options cacheChainLength() {
+    Options options;
+    options.cacheChainLength = true;
+    return options;
+  }
+
   explicit IOBufQueue(const Options& options = Options());
 
+  /**
+   * Return a space to prepend bytes and the amount of headroom available.
+   */
+  std::pair<void*, uint32_t> headroom();
+
+  /**
+   * Indicate that n bytes from the headroom have been used.
+   */
+  void markPrepended(uint32_t n);
+
+  /**
+   * Prepend an existing range; throws std::overflow_error if not enough
+   * room.
+   */
+  void prepend(const void* buf, uint32_t n);
+
   /**
    * Add a buffer or buffer chain to the end of this queue. The
    * queue takes ownership of buf.
@@ -85,9 +114,11 @@ class IOBufQueue {
   /**
    * Obtain a writable block of contiguous bytes at the end of this
    * queue, allocating more space if necessary.  The amount of space
-   * reserved will be between min and max, inclusive; the IOBufQueue
-   * implementation may pick a value in that range that makes efficient
-   * use of already-allocated internal space.
+   * reserved will be at least min.  If min contiguous space is not
+   * available at the end of the queue, and IOBuf with size newAllocationSize
+   * is appended to the chain and returned.  The actual available space
+   * may be larger than newAllocationSize, but will be truncated to max,
+   * if specified.
    *
    * If the caller subsequently writes anything into the returned space,
    * it must call the postallocate() method.
@@ -100,7 +131,9 @@ class IOBufQueue {
    *       callback, tell the application how much of the buffer they've
    *       filled with data.
    */
-  std::pair<void*,uint32_t> preallocate(uint32_t min, uint32_t max);
+  std::pair<void*,uint32_t> preallocate(
+    uint32_t min, uint32_t newAllocationSize,
+    uint32_t max = std::numeric_limits<uint32_t>::max());
 
   /**
    * Tell the queue that the caller has written data into the first n
@@ -114,6 +147,16 @@ class IOBufQueue {
    */
   void postallocate(uint32_t n);
 
+  /**
+   * 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* p = preallocate(n, n).first;
+    postallocate(n);
+    return p;
+  }
+
   /**
    * Split off the first n bytes of the queue into a separate IOBuf chain,
    * and transfer ownership of the new chain to the caller.  The IOBufQueue
@@ -143,7 +186,7 @@ class IOBufQueue {
   /**
    * Transfer ownership of the queue's entire IOBuf chain to the caller.
    */
-  std::unique_ptr<folly::IOBuf>&& move() {
+  std::unique_ptr<folly::IOBuf> move() {
     chainLength_ = 0;
     return std::move(head_);
   }