added IOBuf::wrapBufferAsValue()
authorIlya Maykov <ilyam@fb.com>
Wed, 18 May 2016 01:53:27 +0000 (18:53 -0700)
committerFacebook Github Bot 4 <facebook-github-bot-4-bot@fb.com>
Wed, 18 May 2016 02:08:40 +0000 (19:08 -0700)
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

folly/io/IOBuf.cpp
folly/io/IOBuf.h
folly/io/test/IOBufTest.cpp

index c3b22221f58fa0c9ac1e2eb256195b44e033d0e2..603e75f745cb1d1dbf806a90f34d1caa47849a7d 100644 (file)
@@ -332,6 +332,10 @@ unique_ptr<IOBuf> IOBuf::wrapBuffer(const void* buf, uint64_t capacity) {
   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 {
 }
 
index 32ce6e0de6c7fe833148445f81d291e1a82b7981..318782b4353884ed777ccfbac7279e9eb9c87e01 100644 (file)
@@ -371,6 +371,16 @@ class IOBuf {
   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);
 
index c283db0518f9c5d4f1aa4e5ecf057e5f7cdf0574..f2308b7c1b73019272108f3958eff8f4f4219178 100644 (file)
@@ -186,6 +186,14 @@ TEST(IOBuf, WrapBuffer) {
   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) {