]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/buffer: add function bufferlist::claim_append_piecewise(list& bl).
authorJianpeng Ma <jianpeng.ma@intel.com>
Tue, 20 Jun 2017 23:04:51 +0000 (07:04 +0800)
committerJianpeng Ma <jianpeng.ma@intel.com>
Tue, 20 Jun 2017 23:04:51 +0000 (07:04 +0800)
This only useful for bl is bufferlist::page_aligned_appender. Using
this function can remove memcopy for continue ptrs.
Because page_aligned_appender::flush will split a ptr into two or
more ptrs. For this case, rebuild_aligned_size_and_memory can't handle,
it  will rebuild.

For example
a=bl.get_page_aligned_appender(1);
a.append(3K)
a.flush();
t.claim_append(bl);
a.append(1K);
a.flush();
t.claim_append(bl);

dst.claim_append(t);
//3K and 1K ptr are continue in memory. But they are two ptrs..
dst.is_aligned_size_and_memory(4096,4096) is false.

We add new function claim_append_piecewise() to specially
handle this case.

Signed-off-by: Jianpeng Ma <jianpeng.ma@intel.com>
src/common/buffer.cc
src/include/buffer.h
src/test/bufferlist.cc

index c8570b439d88e57e608bb109110a81d049050194..44ce5b016ece4fc5f8b5240a5ddf4bba3a85f955 100644 (file)
@@ -1815,6 +1815,16 @@ static std::atomic_flag buffer_debug_lock = ATOMIC_FLAG_INIT;
     bl.last_p = bl.begin();
   }
 
+  void buffer::list::claim_append_piecewise(list& bl)
+  {
+    // steal the other guy's buffers
+    for (std::list<buffer::ptr>::const_iterator i = bl.buffers().begin();
+        i != bl.buffers().end(); i++) {
+      append(*i, 0, i->length());
+    }
+    bl.clear();
+  }
+
   void buffer::list::copy(unsigned off, unsigned len, char *dest) const
   {
     if (off + len > length())
index 8f88ec913dc1cb613b11a56802bb9e9d1dffcd32..d9c92ce64d6eef8375b6fe26209df9ce7d8e8dee 100644 (file)
@@ -788,6 +788,8 @@ namespace buffer CEPH_BUFFER_API {
     void claim(list& bl, unsigned int flags = CLAIM_DEFAULT);
     void claim_append(list& bl, unsigned int flags = CLAIM_DEFAULT);
     void claim_prepend(list& bl, unsigned int flags = CLAIM_DEFAULT);
+    // only for bl is bufferlist::page_aligned_appender
+    void claim_append_piecewise(list& bl);
 
     // clone non-shareable buffers (make shareable)
     void make_shareable() {
index b2d408e26450d026b6bfbe45e5d14c3e0cb6de1a..983b4ef750cc65abdda194aa43551da532c9cbb0 100644 (file)
@@ -2097,6 +2097,27 @@ TEST(BufferList, claim_prepend) {
   EXPECT_EQ((unsigned)0, from.length());
 }
 
+TEST(BufferList, claim_append_piecewise) {
+  bufferlist bl, t, dst;
+  auto a = bl.get_page_aligned_appender(4);
+  for (uint32_t i = 0; i < (CEPH_PAGE_SIZE + CEPH_PAGE_SIZE - 1333); i++)
+    a.append("x", 1);
+  a.flush();
+  const char *p = bl.c_str();
+  t.claim_append(bl);
+
+  for (uint32_t i = 0; i < (CEPH_PAGE_SIZE + 1333); i++)
+    a.append("x", 1);
+  a.flush();
+  t.claim_append(bl);
+
+  EXPECT_FALSE(t.is_aligned_size_and_memory(CEPH_PAGE_SIZE, CEPH_PAGE_SIZE));
+  dst.claim_append_piecewise(t);
+  EXPECT_TRUE(dst.is_aligned_size_and_memory(CEPH_PAGE_SIZE, CEPH_PAGE_SIZE));
+  const char *p1 = dst.c_str();
+  EXPECT_TRUE(p == p1);
+}
+
 TEST(BufferList, begin) {
   bufferlist bl;
   bl.append("ABC");