]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
include, test: Add CompatSet::merge() operation
authorDavid Zafman <david.zafman@inktank.com>
Wed, 18 Sep 2013 00:04:54 +0000 (17:04 -0700)
committerDavid Zafman <david.zafman@inktank.com>
Thu, 26 Sep 2013 18:29:04 +0000 (11:29 -0700)
New func merge() adds missing features from specified CompatSet
Add merge testing to unittest

Signed-off-by: David Zafman <david.zafman@inktank.com>
src/include/CompatSet.h
src/test/ceph_compatset.cc

index 31246e186b2d8f44faff4b011c601341dcc77bd0..b23883093acd747725d83e89a23879d0190dfc81 100644 (file)
@@ -171,6 +171,33 @@ struct CompatSet {
     return diff;
   }
   
+  /* Merge features supported by other CompatSet into this one.
+   * Return: true if some features were merged
+   */
+  bool merge(CompatSet& other) {
+    uint64_t other_compat =
+      ((other.compat.mask ^ compat.mask) & other.compat.mask);
+    uint64_t other_ro_compat =
+      ((other.ro_compat.mask ^ ro_compat.mask) & other.ro_compat.mask);
+    uint64_t other_incompat =
+      ((other.incompat.mask ^ incompat.mask) & other.incompat.mask);
+    if (!other_compat && !other_ro_compat && !other_incompat)
+      return false;
+    for (int id = 1; id < 64; ++id) {
+      uint64_t mask = (uint64_t)1 << id;
+      if (mask & other_compat) {
+       compat.insert( Feature(id, other.compat.names[id]));
+      }
+      if (mask & other_ro_compat) {
+       ro_compat.insert(Feature(id, other.ro_compat.names[id]));
+      }
+      if (mask & other_incompat) {
+       incompat.insert( Feature(id, other.incompat.names[id]));
+      }
+    }
+    return true;
+  }
+
   void encode(bufferlist& bl) const {
     compat.encode(bl);
     ro_compat.encode(bl);
index 50909ed0538cb0b3143e72de6850c2da9c393e60..2b57db01ab95b2201ac7637809a3490879cd0713 100644 (file)
@@ -128,3 +128,37 @@ TEST(CephCompatSet, other) {
   EXPECT_EQ(diff.ro_compat.mask, (uint64_t)1);
   EXPECT_EQ(diff.incompat.mask, (uint64_t)1<<4 | 1);
 }
+
+TEST(CephCompatSet, merge) {
+  CompatSet s1, s2, s1dup, s2dup;
+
+  s1.compat.insert(CompatSet::Feature(1, "c1"));
+  s1.compat.insert(CompatSet::Feature(2, "c2"));
+  s1.compat.insert(CompatSet::Feature(32, "c32"));
+  s1.ro_compat.insert(CompatSet::Feature(63, "r63"));
+  s1.incompat.insert(CompatSet::Feature(1, "i1"));
+
+  s1dup = s1;
+
+  s2.compat.insert(CompatSet::Feature(1, "c1"));
+  s2.compat.insert(CompatSet::Feature(32, "c32"));
+  s2.ro_compat.insert(CompatSet::Feature(1, "r1"));
+  s2.ro_compat.insert(CompatSet::Feature(63, "r63"));
+  s2.incompat.insert(CompatSet::Feature(1, "i1"));
+
+  s2dup = s2;
+
+  //Nothing to merge if they are the same
+  EXPECT_FALSE(s1.merge(s1dup));
+  EXPECT_FALSE(s2.merge(s2dup));
+
+  EXPECT_TRUE(s1.merge(s2));
+  EXPECT_EQ(s1.compat.mask, (uint64_t)1<<1 | (uint64_t)1<<2 | (uint64_t)1<<32 | 1);
+  EXPECT_EQ(s1.ro_compat.mask, (uint64_t)1<<1 | (uint64_t)1<<63 | 1);
+  EXPECT_EQ(s1.incompat.mask, (uint64_t)1<<1 | 1);
+
+  EXPECT_TRUE(s2.merge(s1dup));
+  EXPECT_EQ(s2.compat.mask, (uint64_t)1<<1 | (uint64_t)1<<2 | (uint64_t)1<<32 | 1);
+  EXPECT_EQ(s2.ro_compat.mask, (uint64_t)1<<1 | (uint64_t)1<<63 | 1);
+  EXPECT_EQ(s2.incompat.mask, (uint64_t)1<<1 | 1);
+}