Summary:
Added a version of IOBuf::wrapBuffer() which returns the new IOBuf by value rather than heap-allocating it.
Motivation: we have a lot of places in the crypto code that do something like this:
// take a string or vector parameter
auto buf = folly::IOBuf::wrapBuffer( /* string or vector goes here */);
// do something with buf
// return
In these cases, a stack-allocated IOBuf would save us from an unnecessary heap allocation. But calling `folly::IOBuf(folly::IOBuf::WrapBufferOp::WRAP_BUFFER, ...)` is gross and in practice people just call the much more readable `wrapBuffer()` function. Hypothesis: readability trumps performance, but if we had a readable version that returned a stack-allocated IOBuf, it might see usage.
Reviewed By: yfeldblum
Differential Revision:
D3314037
fbshipit-source-id:
4d4b5ec1d067762a27de1d7d6f7cac406388bfa3
return make_unique<IOBuf>(WRAP_BUFFER, buf, capacity);
}
+IOBuf IOBuf::wrapBufferAsValue(const void* buf, uint64_t capacity) {
+ return IOBuf(WrapBufferOp::WRAP_BUFFER, buf, capacity);
+}
+
IOBuf::IOBuf() noexcept {
}
static std::unique_ptr<IOBuf> wrapBuffer(ByteRange br) {
return wrapBuffer(br.data(), br.size());
}
+
+ /**
+ * Similar to wrapBuffer(), but returns IOBuf by value rather than
+ * heap-allocating it.
+ */
+ static IOBuf wrapBufferAsValue(const void* buf, uint64_t capacity);
+ static IOBuf wrapBufferAsValue(ByteRange br) {
+ return wrapBufferAsValue(br.data(), br.size());
+ }
+
IOBuf(WrapBufferOp op, const void* buf, uint64_t capacity);
IOBuf(WrapBufferOp op, ByteRange br);
EXPECT_EQ(size3, iobuf3.length());
EXPECT_EQ(buf3.get(), iobuf3.buffer());
EXPECT_EQ(size3, iobuf3.capacity());
+
+ const uint32_t size4 = 2345;
+ unique_ptr<uint8_t[]> buf4(new uint8_t[size4]);
+ IOBuf iobuf4 = IOBuf::wrapBufferAsValue(buf4.get(), size4);
+ EXPECT_EQ(buf4.get(), iobuf4.data());
+ EXPECT_EQ(size4, iobuf4.length());
+ EXPECT_EQ(buf4.get(), iobuf4.buffer());
+ EXPECT_EQ(size4, iobuf4.capacity());
}
TEST(IOBuf, CreateCombined) {