Commit bd69c0fb authored by Tudor Bosman's avatar Tudor Bosman

Add IOBufQueue::wrapBuffer, which handles buffers > 4GB.

Test Plan: test added

Reviewed By: brianp@fb.com

FB internal diff: D489158
parent 9038adb2
......@@ -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) {
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment