]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: implement ObjectIterator copying and assignment 1294/head
authorJosh Durgin <josh.durgin@inktank.com>
Fri, 21 Feb 2014 01:28:11 +0000 (17:28 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Sat, 22 Feb 2014 02:22:54 +0000 (18:22 -0800)
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 <josh.durgin@inktank.com>
src/include/rados/librados.hpp
src/librados/librados.cc
src/test/librados/list.cc

index a7cd2d66c0ac43916ff99b70a27a478cafa814fb..ac2a011ef9dec53ecd7bca4196fa36c7658c74af 100644 (file)
@@ -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<std::string, std::string>& operator*() const;
index 5950a93a64abf6d808efe2624497288b7e09fcd9..040bf251d13eda63ffc7fbe3347111c056069315 100644 (file)
@@ -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();
index 1c8e4df947b98a95e1131fc17b0e58a617edf22c..69c006e562e6f597c471ea52c5bc5bfb131c10b2 100644 (file)
@@ -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<std::string>& myset, rados_list_ctx_t& ctx)
 {
   const char *entry;