BENCHMARK(cloneIntoBenchmark, iters) { IOBuf buf(IOBuf::CREATE, 10); IOBuf copy; while (iters--) { buf.cloneInto(copy); folly::doNotOptimizeAway(copy.capacity()); } }
TEST(IOBuf, move) { // Default allocate an IOBuf on the stack IOBuf outerBuf; char data[] = "foobar"; uint32_t length = sizeof(data); uint32_t actualCapacity{0}; const void* ptr{nullptr}; { // Create a small IOBuf on the stack. // Note that IOBufs created on the stack always use an external buffer. IOBuf b1(IOBuf::CREATE, 10); actualCapacity = b1.capacity(); EXPECT_GE(actualCapacity, 10); EXPECT_EQ(0, b1.length()); EXPECT_FALSE(b1.isShared()); ptr = b1.data(); ASSERT_TRUE(ptr != nullptr); memcpy(b1.writableTail(), data, length); b1.append(length); EXPECT_EQ(length, b1.length()); // Use the move constructor IOBuf b2(std::move(b1)); EXPECT_EQ(ptr, b2.data()); EXPECT_EQ(length, b2.length()); EXPECT_EQ(actualCapacity, b2.capacity()); EXPECT_FALSE(b2.isShared()); // Use the move assignment operator outerBuf = std::move(b2); // Close scope, destroying b1 and b2 // (which are both be invalid now anyway after moving out of them) } EXPECT_EQ(ptr, outerBuf.data()); EXPECT_EQ(length, outerBuf.length()); EXPECT_EQ(actualCapacity, outerBuf.capacity()); EXPECT_FALSE(outerBuf.isShared()); }