From bd69c0fbbdc75a9c3845620196f15b3eecd4ed5c Mon Sep 17 00:00:00 2001 From: Tudor Bosman Date: Thu, 7 Jun 2012 13:59:38 -0700 Subject: [PATCH] Add IOBufQueue::wrapBuffer, which handles buffers > 4GB. Test Plan: test added Reviewed By: brianp@fb.com FB internal diff: D489158 --- folly/experimental/io/IOBufQueue.cpp | 11 +++++++++++ folly/experimental/io/IOBufQueue.h | 15 +++++++++++++++ folly/experimental/io/test/IOBufQueueTest.cpp | 16 ++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/folly/experimental/io/IOBufQueue.cpp b/folly/experimental/io/IOBufQueue.cpp index 4b6e5eab..35295bf8 100644 --- a/folly/experimental/io/IOBufQueue.cpp +++ b/folly/experimental/io/IOBufQueue.cpp @@ -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(buf); + while (len != 0) { + size_t n = std::min(len, size_t(blockSize)); + append(IOBuf::wrapBuffer(src, n)); + src += n; + len -= n; + } +} + pair IOBufQueue::preallocate(uint32_t min, uint32_t max) { if (head_ != NULL) { diff --git a/folly/experimental/io/IOBufQueue.h b/folly/experimental/io/IOBufQueue.h index 7806e7d2..7c25c621 100644 --- a/folly/experimental/io/IOBufQueue.h +++ b/folly/experimental/io/IOBufQueue.h @@ -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 diff --git a/folly/experimental/io/test/IOBufQueueTest.cpp b/folly/experimental/io/test/IOBufQueueTest.cpp index 58f727a5..9562c204 100644 --- a/folly/experimental/io/test/IOBufQueueTest.cpp +++ b/folly/experimental/io/test/IOBufQueueTest.cpp @@ -15,6 +15,7 @@ */ #include "folly/experimental/io/IOBufQueue.h" +#include "folly/Range.h" #include #include @@ -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(iob->data()), + iob->length())); +} + TEST(IOBufQueue, trim) { IOBufQueue queue(clOptions); unique_ptr a = IOBuf::create(4); -- 2.34.1