diff options
author | David Zafman <david.zafman@inktank.com> | 2013-09-17 17:04:54 -0700 |
---|---|---|
committer | David Zafman <david.zafman@inktank.com> | 2013-09-26 11:29:04 -0700 |
commit | 793ba9f1d551f66f1aefa4e2f78ef5592a74b7e0 (patch) | |
tree | 729347adb04994f2afd7e49e8782ab453453456c | |
parent | c6b83180f9f769de27ca7890f5f8ec507ee743ca (diff) | |
download | ceph-793ba9f1d551f66f1aefa4e2f78ef5592a74b7e0.tar.gz |
include, test: Add CompatSet::merge() operation
New func merge() adds missing features from specified CompatSet
Add merge testing to unittest
Signed-off-by: David Zafman <david.zafman@inktank.com>
-rw-r--r-- | src/include/CompatSet.h | 27 | ||||
-rw-r--r-- | src/test/ceph_compatset.cc | 34 |
2 files changed, 61 insertions, 0 deletions
diff --git a/src/include/CompatSet.h b/src/include/CompatSet.h index 31246e186b2..b23883093ac 100644 --- a/src/include/CompatSet.h +++ b/src/include/CompatSet.h @@ -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); diff --git a/src/test/ceph_compatset.cc b/src/test/ceph_compatset.cc index 50909ed0538..2b57db01ab9 100644 --- a/src/test/ceph_compatset.cc +++ b/src/test/ceph_compatset.cc @@ -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); +} |