From 0da25e6746a5542206b948771a110fa5c085aaeb Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Thu, 20 Feb 2014 17:28:11 -0800 Subject: [PATCH] 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 --- src/include/rados/librados.hpp | 3 +++ src/librados/librados.cc | 15 +++++++++++++++ src/test/librados/list.cc | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index a7cd2d66c0ac..ac2a011ef9de 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 5950a93a64ab..040bf251d13e 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 1c8e4df947b9..69c006e562e6 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; -- 2.47.3