return p - 1;
}
+bool pg_t::is_merge(unsigned old_pg_num, unsigned new_pg_num,
+ pg_t *parent) const
+{
+ if (m_seed < old_pg_num &&
+ m_seed >= new_pg_num) {
+ if (parent) {
+ pg_t t = *this;
+ while (t.m_seed >= new_pg_num) {
+ t = t.get_parent();
+ }
+ *parent = t;
+ }
+ return true;
+ }
+ return false;
+}
+
pg_t pg_t::get_parent() const
{
unsigned bits = cbits(m_seed);
bool is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t> *pchildren) const;
+ bool is_merge(unsigned old_pg_num, unsigned new_pg_num, pg_t *parent) const;
+
/**
* Returns b such that for all object o:
* ~((~0)<<b) & o.hash) == 0 iff o is in the pg for *this
}
return is_split;
}
+ bool is_merge(unsigned old_pg_num, unsigned new_pg_num, spg_t *parent) const {
+ spg_t out = *this;
+ bool r = pgid.is_merge(old_pg_num, new_pg_num, &out.pgid);
+ if (r && parent) {
+ *parent = out;
+ }
+ return r;
+ }
+
bool is_no_shard() const {
return shard == shard_id_t::NO_SHARD;
}
}
+TEST(pg_t, merge)
+{
+ pg_t pgid, parent;
+ bool b;
+
+ pgid = pg_t(7, 0);
+ b = pgid.is_merge(8, 7, &parent);
+ ASSERT_TRUE(b);
+ ASSERT_EQ(parent, pg_t(3, 0));
+
+ b = pgid.is_merge(8, 5, &parent);
+ ASSERT_TRUE(b);
+ ASSERT_EQ(parent, pg_t(3, 0));
+
+ b = pgid.is_merge(8, 4, &parent);
+ ASSERT_TRUE(b);
+ ASSERT_EQ(parent, pg_t(3, 0));
+
+ b = pgid.is_merge(8, 3, &parent);
+ ASSERT_TRUE(b);
+ ASSERT_EQ(parent, pg_t(1, 0));
+
+ b = pgid.is_merge(9, 8, &parent);
+ ASSERT_FALSE(b);
+}
+
TEST(pg_missing_t, constructor)
{
pg_missing_t missing;