From: Jianpeng Ma Date: Tue, 20 Jun 2017 23:04:51 +0000 (+0800) Subject: common/buffer: add function bufferlist::claim_append_piecewise(list& bl). X-Git-Tag: v12.1.0~34^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=434656c6106479705a5e71db8843b4a272d13b88;p=ceph.git common/buffer: add function bufferlist::claim_append_piecewise(list& bl). 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 --- diff --git a/src/common/buffer.cc b/src/common/buffer.cc index c8570b439d88..44ce5b016ece 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -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::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()) diff --git a/src/include/buffer.h b/src/include/buffer.h index 8f88ec913dc1..d9c92ce64d6e 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -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() { diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc index b2d408e26450..983b4ef750cc 100644 --- a/src/test/bufferlist.cc +++ b/src/test/bufferlist.cc @@ -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");