]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
DBObjectMap: strengthen in_complete_region post condition
authorSamuel Just <sjust@redhat.com>
Fri, 10 Feb 2017 23:50:57 +0000 (15:50 -0800)
committerDavid Zafman <dzafman@redhat.com>
Tue, 28 Mar 2017 16:32:46 +0000 (09:32 -0700)
Previously, in_complete_region didn't guarantee anything about
where it left complete_iter pointing.  It will be handy for
complete_iter to be pointing at the lowest interval which ends
after to_test.  Make it so.

Signed-off-by: Samuel Just <sjust@redhat.com>
(cherry picked from commit 97b35f4d7d4862da4b6f50ecaef0d292a671fd04)

src/os/filestore/DBObjectMap.cc
src/os/filestore/DBObjectMap.h

index 97833925d4994e0a3f2a696822c4424c8c8e061c..6ea5278b14229c3b8014ecd659c878ed9901eb82 100644 (file)
@@ -395,22 +395,37 @@ int DBObjectMap::DBObjectMapIteratorImpl::in_complete_region(const string &to_te
                                                             string *begin,
                                                             string *end)
 {
+  /* This is clumsy because one cannot call prev() on end(), nor can one
+   * test for == begin().
+   */
   complete_iter->upper_bound(to_test);
-  if (complete_iter->valid())
+  if (complete_iter->valid()) {
     complete_iter->prev();
-  else
+    if (!complete_iter->valid()) {
+      complete_iter->upper_bound(to_test);
+      return false;
+    }
+  } else {
     complete_iter->seek_to_last();
+    if (!complete_iter->valid())
+      return false;
+  }
 
-  if (!complete_iter->valid())
+  assert(complete_iter->key() <= to_test);
+  assert(complete_iter->value().length() >= 1);
+  string _end(complete_iter->value().c_str(),
+             complete_iter->value().length() - 1);
+  if (_end.empty() || _end > to_test) {
+    if (begin)
+      *begin = complete_iter->key();
+    if (end)
+      *end = _end;
+    return true;
+  } else {
+    complete_iter->next();
+    assert(!complete_iter->valid() || complete_iter->key() > to_test);
     return false;
-
-  string _end;
-  if (begin)
-    *begin = complete_iter->key();
-  _end = string(complete_iter->value().c_str());
-  if (end)
-    *end = _end;
-  return (to_test >= complete_iter->key()) && (!_end.size() || _end > to_test);
+  }
 }
 
 /**
index 2b3b9f4dcb3341672a55ddfb7bd1a5f648d22c5f..8a06cad930218ba013909e409d8fe2ab3516bc2b 100644 (file)
@@ -405,6 +405,11 @@ private:
     int next_parent();
 
     /// Tests whether to_test is in complete region
+    /**
+     * Tests whether to_test is in complete region
+     *
+     * postcondition: complete_iter will be max s.t. complete_iter->value > to_test
+     */
     int in_complete_region(const string &to_test, ///< [in] key to test
                           string *begin,         ///< [out] beginning of region
                           string *end            ///< [out] end of region