Add IOBufQueue::wrapBuffer, which handles buffers > 4GB.
authorTudor Bosman <tudorb@fb.com>
Thu, 7 Jun 2012 20:59:38 +0000 (13:59 -0700)
committerTudor Bosman <tudorb@fb.com>
Fri, 8 Jun 2012 18:28:32 +0000 (11:28 -0700)
Test Plan: test added

Reviewed By: brianp@fb.com

FB internal diff: D489158

folly/experimental/io/IOBufQueue.cpp
folly/experimental/io/IOBufQueue.h
folly/experimental/io/test/IOBufQueueTest.cpp

index 4b6e5eab80589b2a4e7d42cec5d7355f371131c1..35295bf87fcba5ff1426d7580afe6192c272a7fe 100644 (file)
@@ -118,6 +118,17 @@ IOBufQueue::append(const void* buf, size_t len) {
   }
 }
 
+void
+IOBufQueue::wrapBuffer(const void* buf, size_t len, uint32_t blockSize) {
+  auto src = static_cast<const uint8_t*>(buf);
+  while (len != 0) {
+    size_t n = std::min(len, size_t(blockSize));
+    append(IOBuf::wrapBuffer(src, n));
+    src += n;
+    len -= n;
+  }
+}
+
 pair<void*,uint32_t>
 IOBufQueue::preallocate(uint32_t min, uint32_t max) {
   if (head_ != NULL) {
index 7806e7d29fcc99dc74cf4bb723b34369d7f75447..7c25c62157eaa999e264143b5b25d16234c1ca4d 100644 (file)
@@ -67,6 +67,21 @@ class IOBufQueue {
     append(buf.data(), buf.length());
   }
 
+  /**
+   * Append a chain of IOBuf objects that point to consecutive regions
+   * within buf.
+   *
+   * Just like IOBuf::wrapBuffer, this should only be used when the caller
+   * knows ahead of time and can ensure that all IOBuf objects that will point
+   * to this buffer will be destroyed before the buffer itself is destroyed;
+   * all other caveats from wrapBuffer also apply.
+   *
+   * Every buffer except for the last will wrap exactly blockSize bytes.
+   * 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
+
   /**
    * Obtain a writable block of contiguous bytes at the end of this
    * queue, allocating more space if necessary.  The amount of space
index 58f727a5e07d59a282580fcde56310a72d75deee..9562c2040bc62c966dbbc4e56e5ed7cee981ce73 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "folly/experimental/io/IOBufQueue.h"
+#include "folly/Range.h"
 
 #include <gflags/gflags.h>
 #include <gtest/gtest.h>
@@ -25,6 +26,7 @@
 
 using folly::IOBuf;
 using folly::IOBufQueue;
+using folly::StringPiece;
 using std::pair;
 using std::string;
 using std::unique_ptr;
@@ -165,6 +167,20 @@ TEST(IOBufQueue, Preallocate) {
   EXPECT_GE(4096, writable.second);
 }
 
+TEST(IOBufQueue, Wrap) {
+  IOBufQueue queue(clOptions);
+  const char* buf = "hello world goodbye";
+  size_t len = strlen(buf);
+  queue.wrapBuffer(buf, len, 6);
+  auto iob = queue.move();
+  EXPECT_EQ((len - 1) / 6 + 1, iob->countChainElements());
+  iob->unshare();
+  iob->coalesce();
+  EXPECT_EQ(StringPiece(buf),
+            StringPiece(reinterpret_cast<const char*>(iob->data()),
+                        iob->length()));
+}
+
 TEST(IOBufQueue, trim) {
   IOBufQueue queue(clOptions);
   unique_ptr<IOBuf> a = IOBuf::create(4);