osd: pg_t::is_split(): make children out param a pointer, and optional

Also unit test it.

Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
Sage Weil 2012-02-27 14:35:21 -08:00
parent 85ed06e973
commit b6a04174bc
4 changed files with 18 additions and 8 deletions

View File

@ -3654,7 +3654,7 @@ void OSD::advance_map(ObjectStore::Transaction& t, C_Contexts *tfin)
pg_t pgid = it->first;
PG *pg = it->second;
set<pg_t> children;
if (pgid.is_split(p->second, pg->pool->info.pg_num, children)) {
if (pgid.is_split(p->second, pg->pool->info.pg_num, &children)) {
do_split(pg, children, t, tfin);
}
}

View File

@ -180,12 +180,13 @@ bool pg_t::parse(const char *s)
return true;
}
bool pg_t::is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t>& children) const
bool pg_t::is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t> *children) const
{
assert(m_seed < old_pg_num);
if (new_pg_num <= old_pg_num)
return false;
bool split = false;
if (true) {
int old_bits = pg_pool_t::calc_bits_of(old_pg_num);
int old_mask = (1 << old_bits) - 1;
@ -197,8 +198,11 @@ bool pg_t::is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t>& childre
continue;
if (s >= new_pg_num)
break;
if ((unsigned)ceph_stable_mod(s, old_pg_num, old_mask) == m_seed)
children.insert(pg_t(s, m_pool, m_preferred));
if ((unsigned)ceph_stable_mod(s, old_pg_num, old_mask) == m_seed) {
split = true;
if (children)
children->insert(pg_t(s, m_pool, m_preferred));
}
}
}
if (false) {
@ -207,11 +211,13 @@ bool pg_t::is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t>& childre
int old_mask = (1 << old_bits) - 1;
for (unsigned x = old_pg_num; x < new_pg_num; ++x) {
unsigned o = ceph_stable_mod(x, old_pg_num, old_mask);
if (o == m_seed)
children.insert(pg_t(x, m_pool, m_preferred));
if (o == m_seed) {
split = true;
children->insert(pg_t(x, m_pool, m_preferred));
}
}
}
return !children.empty();
return split;
}
void pg_t::dump(Formatter *f) const

View File

@ -238,7 +238,7 @@ struct pg_t {
int print(char *o, int maxlen) const;
bool parse(const char *s);
bool is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t>& children) const;
bool is_split(unsigned old_pg_num, unsigned new_pg_num, set<pg_t> *pchildren) const;
void encode(bufferlist& bl) const {
__u8 v = 1;

View File

@ -30,6 +30,8 @@ TEST(pg_t, split)
ASSERT_TRUE(!b);
s.clear();
b = pgid.is_split(2, 4, NULL);
ASSERT_TRUE(b);
b = pgid.is_split(2, 4, s);
ASSERT_TRUE(b);
ASSERT_EQ(1u, s.size());
@ -50,6 +52,8 @@ TEST(pg_t, split)
ASSERT_TRUE(s.count(pg_t(4, 0, -1)));
s.clear();
b = pgid.is_split(6, 8, NULL);
ASSERT_TRUE(!b);
b = pgid.is_split(6, 8, s);
ASSERT_TRUE(!b);
ASSERT_EQ(0u, s.size());