From: Josh Durgin Date: Fri, 21 Feb 2014 01:28:11 +0000 (-0800) Subject: librados: implement ObjectIterator copying and assignment X-Git-Tag: v0.78~129^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F1294%2Fhead;p=ceph.git librados: implement ObjectIterator copying and assignment Copied iterators should be independent of each other, and not rely on the same underlying ListContext or ObjListCtx. Add some tests for this to make sure they work in various circumstances. Signed-off-by: Josh Durgin --- diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index a7cd2d66c0a..ac2a011ef9d 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -64,6 +64,9 @@ namespace librados ObjectIterator() {} ObjectIterator(ObjListCtx *ctx_); ~ObjectIterator(); + ObjectIterator(const ObjectIterator &rhs); + ObjectIterator& operator=(const ObjectIterator& rhs); + bool operator==(const ObjectIterator& rhs) const; bool operator!=(const ObjectIterator& rhs) const; const std::pair& operator*() const; diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 5950a93a64a..040bf251d13 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -480,6 +480,21 @@ librados::ObjectIterator::~ObjectIterator() ctx.reset(); } +librados::ObjectIterator::ObjectIterator(const ObjectIterator &rhs) +{ + *this = rhs; +} + +librados::ObjectIterator& librados::ObjectIterator::operator=(const librados::ObjectIterator &rhs) +{ + if (&rhs == this) + return *this; + Objecter::ListContext *list_ctx = new Objecter::ListContext(*rhs.ctx->lc); + ctx.reset(new ObjListCtx(rhs.ctx->ctx, list_ctx)); + cur_obj = rhs.cur_obj; + return *this; +} + bool librados::ObjectIterator::operator==(const librados::ObjectIterator& rhs) const { if (ctx.get() == NULL) return rhs.ctx.get() == NULL || rhs.ctx->lc->at_end(); diff --git a/src/test/librados/list.cc b/src/test/librados/list.cc index 1c8e4df947b..69c006e562e 100644 --- a/src/test/librados/list.cc +++ b/src/test/librados/list.cc @@ -73,6 +73,38 @@ TEST_F(LibRadosListPP, ListObjectsTwicePP) { ASSERT_TRUE(foundit); } +TEST_F(LibRadosListPP, ListObjectsCopyIterPP) { + char buf[128]; + memset(buf, 0xcc, sizeof(buf)); + bufferlist bl1; + bl1.append(buf, sizeof(buf)); + ASSERT_EQ((int)sizeof(buf), ioctx.write("foo", bl1, sizeof(buf), 0)); + + // make sure this is still valid after the original iterators are gone + ObjectIterator iter3; + { + ObjectIterator iter(ioctx.objects_begin()); + ObjectIterator iter2(iter); + iter3 = iter2; + ASSERT_EQ((*iter).first, "foo"); + ++iter; + ASSERT_TRUE(iter == ioctx.objects_end()); + ++iter; + ASSERT_TRUE(iter == ioctx.objects_end()); + + ASSERT_EQ(iter2->first, "foo"); + ASSERT_EQ(iter3->first, "foo"); + ++iter2; + ASSERT_TRUE(iter2 == ioctx.objects_end()); + } + + ASSERT_EQ(iter3->first, "foo"); + iter3 = iter3; + ASSERT_EQ(iter3->first, "foo"); + ++iter3; + ASSERT_TRUE(iter3 == ioctx.objects_end()); +} + static void check_list(std::set& myset, rados_list_ctx_t& ctx) { const char *entry;