]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
MDS: add operator==() and compare() for inode_backtrace_t
authorGreg Farnum <greg@inktank.com>
Thu, 10 Jul 2014 00:09:51 +0000 (17:09 -0700)
committerGreg Farnum <gfarnum@redhat.com>
Fri, 7 Nov 2014 19:48:42 +0000 (11:48 -0800)
The compare() function checks one backtrace against another and indicates
if they're equivalent (or divergent!) and the relative freshness.

Signed-off-by: Greg Farnum <greg@inktank.com>
src/mds/inode_backtrace.cc
src/mds/inode_backtrace.h

index e2ab809db100b039e166571ad382ef21ce816e4c..bde2145ebf247df7e4718fed0c07082b153e16e2 100644 (file)
@@ -118,3 +118,51 @@ void inode_backtrace_t::generate_test_instances(list<inode_backtrace_t*>& ls)
   ls.back()->old_pools.insert(7);
 }
 
+int inode_backtrace_t::compare(const inode_backtrace_t& other,
+                               bool *equivalent, bool *divergent) const
+{
+  int min_size = MIN(ancestors.size(),other.ancestors.size());
+  *divergent = false;
+  if (min_size == 0)
+    return 0;
+  int comparator = 0;
+  if (ancestors[0].version > other.ancestors[0].version)
+    comparator = 1;
+  else if (ancestors[0].version < other.ancestors[0].version)
+    comparator = -1;
+  for (int i = 1; i < min_size; ++i) {
+    if (*divergent) {
+      /**
+       * we already know the dentries and versions are
+       * incompatible; no point checking farther
+       */
+      break;
+    }
+    if (ancestors[i].dirino != other.ancestors[i].dirino) {
+      *equivalent = false;
+      if (ancestors[i-1].version < other.ancestors[i-1].version) {
+        if (comparator > 0)
+          *divergent = true;
+        return -1;
+      } else if (ancestors[i-1].version > other.ancestors[i-1].version) {
+        if (comparator < 0)
+          *divergent = true;
+        return 1;
+      } else {
+        assert(ancestors[i-1].version == other.ancestors[i-1].version);
+        return 0;
+      }
+    } else if (ancestors[i].version > other.ancestors[i].version) {
+      if (comparator < 0)
+        *divergent = true;
+      comparator = 1;
+    } else if (ancestors[i].version < other.ancestors[i].version) {
+      if (comparator > 0)
+        *divergent = true;
+      comparator = -1;
+    }
+  }
+  if (!*divergent)
+    *equivalent = true;
+  return comparator;
+}
index 2d80ae3efadabd712f251b21be819577d1e5a09c..08cbf65af9084c58c841dcc95b7fe74262717516 100644 (file)
@@ -61,6 +61,21 @@ struct inode_backtrace_t {
   void decode(bufferlist::iterator &bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<inode_backtrace_t*>& ls);
+
+  /**
+   * Compare two backtraces *for the same inode*.
+   * @pre The backtraces are for the same inode
+   *
+   * @param other The backtrace to compare ourselves with
+   * @param equivalent A bool pointer which will be set to true if
+   * the other backtrace is equivalent to our own (has the same dentries)
+   * @param divergent A bool pointer which will be set to true if
+   * the backtraces have differing entries without versions supporting them
+   *
+   * @returns 1 if we are newer than the other, 0 if equal, -1 if older
+   */
+  int compare(const inode_backtrace_t& other,
+               bool *equivalent, bool *divergent) const;
 };
 WRITE_CLASS_ENCODER(inode_backtrace_t)
 
@@ -68,6 +83,13 @@ inline ostream& operator<<(ostream& out, const inode_backtrace_t& it) {
   return out << "(" << it.pool << ")" << it.ino << ":" << it.ancestors << "//" << it.old_pools;
 }
 
+inline bool operator==(const inode_backtrace_t& l,
+                       const inode_backtrace_t& r) {
+  return l.ino == r.ino &&
+      l.pool == r.pool &&
+      l.old_pools == r.old_pools &&
+      l.ancestors == r.ancestors;
+}
 
 #endif