From: Sage Weil Date: Fri, 6 May 2016 21:36:01 +0000 (-0400) Subject: buffer: add buffer::list::iterator::get_ptr_and_advance X-Git-Tag: v11.0.0~359^2~112 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e31bf9e2185bf167d507f55db94f416f0dfae414;p=ceph.git buffer: add buffer::list::iterator::get_ptr_and_advance Efficiently iterate over buffers in a list, via an iterator. Signed-off-by: Sage Weil --- diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 3557b3775d4f..baf97828091a 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1198,6 +1198,26 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER; } } + template + size_t buffer::list::iterator_impl::get_ptr_and_advance( + size_t want, const char **data) + { + if (p == ls->end()) { + seek(off); + if (p == ls->end()) { + return 0; + } + } + *data = p->c_str() + p_off; + size_t l = MIN(p->length() - p_off, want); + p_off += l; + if (p_off == p->length()) { + ++p; + p_off = 0; + } + return l; + } + // explicitly instantiate only the iterator types we need, so we can hide the // details in this compilation unit without introducing unnecessary link time // dependencies. diff --git a/src/include/buffer.h b/src/include/buffer.h index 4c5de1d486be..9441cd583d23 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -324,6 +324,11 @@ namespace buffer CEPH_BUFFER_API { void copy(unsigned len, std::string &dest); void copy_all(list &dest); + // get a pointer to the currenet iterator position, return the + // number of bytes we can read from that position (up to want), + // and advance the iterator by that amount. + size_t get_ptr_and_advance(size_t want, const char **p); + friend bool operator==(const iterator_impl& lhs, const iterator_impl& rhs) { return &lhs.get_bl() == &rhs.get_bl() && lhs.get_off() == rhs.get_off(); diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc index 43eb76d8362a..0f1696f46b5b 100644 --- a/src/test/bufferlist.cc +++ b/src/test/bufferlist.cc @@ -1037,6 +1037,27 @@ TEST(BufferListIterator, advance) { } } +TEST(BufferListIterator, get_ptr_and_advance) +{ + bufferptr a("one", 3); + bufferptr b("two", 3); + bufferptr c("three", 5); + bufferlist bl; + bl.append(a); + bl.append(b); + bl.append(c); + const char *ptr; + bufferlist::iterator p = bl.begin(); + ASSERT_EQ(3u, p.get_ptr_and_advance(11, &ptr)); + ASSERT_EQ(0, memcmp(ptr, "one", 3)); + ASSERT_EQ(2u, p.get_ptr_and_advance(2, &ptr)); + ASSERT_EQ(0, memcmp(ptr, "tw", 2)); + ASSERT_EQ(1u, p.get_ptr_and_advance(4, &ptr)); + ASSERT_EQ(0, memcmp(ptr, "o", 1)); + ASSERT_EQ(5u, p.get_ptr_and_advance(5, &ptr)); + ASSERT_EQ(0, memcmp(ptr, "three", 5)); +} + TEST(BufferListIterator, seek) { bufferlist bl; bl.append("ABC", 3);