From: Sage Weil Date: Mon, 20 Jan 2014 18:28:43 +0000 (-0800) Subject: osd: add pg_pool_t::get_pg_num_divisor X-Git-Tag: v0.78~166^2~37 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e65c280b0e4f4ef7bbb4542b21c4ef67f6ee188d;p=ceph.git osd: add pg_pool_t::get_pg_num_divisor A PG is not always an equally sized fraction of the total pool size due to the use of ceph_stable_mod. Add a helper to return the fraction (denominator) of a given pg based on the current pg_num value. Signed-off-by: Sage Weil --- diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 2e43c51abcb7..5018062e207a 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -750,6 +750,17 @@ void pg_pool_t::calc_pg_masks() pgp_num_mask = (1 << calc_bits_of(pgp_num-1)) - 1; } +unsigned pg_pool_t::get_pg_num_divisor(pg_t pgid) const +{ + if (pg_num == pg_num_mask + 1) + return pg_num; // power-of-2 split + unsigned mask = pg_num_mask >> 1; + if ((pgid.ps() & mask) < (pg_num & mask)) + return pg_num_mask + 1; // smaller bin size (already split) + else + return (pg_num_mask + 1) >> 1; // bigger bin (not yet split) +} + /* * we have two snap modes: * - pool global snaps diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index feabbd6e2ea5..5db79572c9fe 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -811,7 +811,7 @@ public: */ interval_set removed_snaps; - int pg_num_mask, pgp_num_mask; + unsigned pg_num_mask, pgp_num_mask; set tiers; ///< pools that are tiers of us int64_t tier_of; ///< pool for which we are a tier @@ -914,6 +914,11 @@ public: unsigned get_pg_num_mask() const { return pg_num_mask; } unsigned get_pgp_num_mask() const { return pgp_num_mask; } + // if pg_num is not a multiple of two, pgs are not equally sized. + // return, for a given pg, the fraction (denominator) of the total + // pool size that it represents. + unsigned get_pg_num_divisor(pg_t pgid) const; + void set_pg_num(int p) { pg_num = p; calc_pg_masks(); diff --git a/src/test/test_osd_types.cc b/src/test/test_osd_types.cc index bcc71c37bd13..ed878695122f 100644 --- a/src/test/test_osd_types.cc +++ b/src/test/test_osd_types.cc @@ -1160,6 +1160,33 @@ TEST_F(ObjectContextTest, read_write_lock) } +TEST(pg_pool_t_test, get_pg_num_divisor) { + pg_pool_t p; + p.set_pg_num(16); + p.set_pgp_num(16); + + for (int i = 0; i < 16; ++i) + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(i, 1))); + + p.set_pg_num(12); + p.set_pgp_num(12); + //cout << "num " << p.get_pg_num() + // << " mask " << p.get_pg_num_mask() << std::endl; + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(0, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(1, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(2, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(3, 1))); + ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(4, 1))); + ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(5, 1))); + ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(6, 1))); + ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(7, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(8, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(9, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(10, 1))); + ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(11, 1))); +} + + /* * Local Variables: * compile-command: "cd .. ;