]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: add pg_pool_t::get_random_pg_position()
authorSage Weil <sage@inktank.com>
Tue, 28 Jan 2014 00:20:04 +0000 (16:20 -0800)
committerSage Weil <sage@inktank.com>
Sun, 16 Feb 2014 06:09:38 +0000 (22:09 -0800)
Return a hash position somewhere inside a given pg.

Signed-off-by: Sage Weil <sage@inktank.com>
src/osd/osd_types.cc
src/osd/osd_types.h
src/test/osd/types.cc

index 5018062e207a5b4c1fe204090734153f39f4cdf9..848dc8b7b722af79a0198a027f9e1bfbe47fcd68 100644 (file)
@@ -910,6 +910,23 @@ ps_t pg_pool_t::raw_pg_to_pps(pg_t pg) const
   }
 }
 
+uint32_t pg_pool_t::get_random_pg_position(pg_t pg, uint32_t seed) const
+{
+  uint32_t r = crush_hash32_2(CRUSH_HASH_RJENKINS1, seed, 123);
+  if (pg_num == pg_num_mask + 1) {
+    r &= ~pg_num_mask;
+  } else {
+    unsigned smaller_mask = pg_num_mask >> 1;
+    if ((pg.ps() & smaller_mask) < (pg_num & smaller_mask)) {
+      r &= ~pg_num_mask;
+    } else {
+      r &= ~smaller_mask;
+    }
+  }
+  r |= pg.ps();
+  return r;
+}
+
 void pg_pool_t::encode(bufferlist& bl, uint64_t features) const
 {
   if ((features & CEPH_FEATURE_PGPOOL3) == 0) {
index 3e32b16a90be61ba4b67d34d8b5ae199e3805e14..8360218790dfb2578ca89eeb62832ecaad5dd403 100644 (file)
@@ -990,6 +990,9 @@ public:
    */
   ps_t raw_pg_to_pps(pg_t pg) const;
 
+  /// choose a random hash position within a pg
+  uint32_t get_random_pg_position(pg_t pgid, uint32_t seed) const;
+
   void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
 
index d1e62b8fceaf3b796b1a749ebf53ede65f42e333..a0d660fa92a5d4981a501985ba129219b35ebb0f 100644 (file)
@@ -1186,6 +1186,20 @@ TEST(pg_pool_t_test, get_pg_num_divisor) {
   ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(11, 1)));
 }
 
+TEST(pg_pool_t_test, get_random_pg_position) {
+  srand(getpid());
+  for (int i = 0; i < 100; ++i) {
+    pg_pool_t p;
+    p.set_pg_num(1 + (rand() % 1000));
+    p.set_pgp_num(p.get_pg_num());
+    pg_t pgid(rand() % p.get_pg_num(), 1);
+    uint32_t h = p.get_random_pg_position(pgid, rand());
+    uint32_t ps = p.raw_hash_to_pg(h);
+    cout << p.get_pg_num() << " " << pgid << ": "
+        << h << " -> " << pg_t(ps, 1) << std::endl;
+    ASSERT_EQ(pgid.ps(), ps);
+  }
+}
 
 /*
  * Local Variables: