]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/bloom_filter: methods for density, approx unique element counts
authorSage Weil <sage@inktank.com>
Sat, 5 Oct 2013 05:50:58 +0000 (22:50 -0700)
committerSage Weil <sage@inktank.com>
Sat, 5 Oct 2013 05:57:35 +0000 (22:57 -0700)
Signed-off-by: Sage Weil <sage@inktank.com>
src/common/bloom_filter.hpp
src/test/common/test_bloom_filter.cc

index c336eef8b6a4951614134f1b7f342fc58a5176e2..4b711526676c1d78f26208392ac9a3da9f6df277 100644 (file)
@@ -296,6 +296,31 @@ public:
     return insert_count_;
   }
 
+  /*
+   * density of bits set.  inconvenient units, but:
+   *    .3  = ~50% target insertions
+   *    .5  = 100% target insertions, "perfectly full"
+   *    .75 = 200% target insertions
+   *   1.0  = all bits set... infinite insertions
+   */
+  inline double density() const
+  {
+    size_t set = 0;
+    uint8_t *p = bit_table_;
+    size_t left = table_size_;
+    while (left-- > 0) {
+      uint8_t c = *p;
+      for (; c; ++set)
+       c &= c - 1;
+      ++p;
+    }
+    return (double)set / (double)(table_size_ << 3);
+  }
+
+  inline double approx_unique_element_count() const {
+    // this is not a very good estimate; a better solution should have
+    // some asymptotic behavior as density() approaches 1.0.
+    return (double)target_element_count_ * 2.0 * density();
   }
 
   inline double effective_fpp() const
index 8e3661b2cc12c067531b3b3a38db298c84f9a9b4..5edf3f0f9fab374ae23f7b68d06d14810b63869a 100644 (file)
@@ -62,7 +62,7 @@ TEST(BloomFilter, Sweep) {
 }
 
 TEST(BloomFilter, SweepInt) {
-  std::cout << "# max\tfpp\tactual\tsize\tB/insert" << std::endl;
+  std::cout << "# max\tfpp\tactual\tsize\tB/insert\tdensity\tapprox_element_count" << std::endl;
   for (int ex = 3; ex < 12; ex += 2) {
     for (float fpp = .001; fpp < .5; fpp *= 4.0) {
       int max = 2 << ex;
@@ -92,7 +92,8 @@ TEST(BloomFilter, SweepInt) {
 
       double byte_per_insert = (double)bl.length() / (double)max;
 
-      std::cout << max << "\t" << fpp << "\t" << actual << "\t" << bl.length() << "\t" << byte_per_insert << std::endl;
+      std::cout << max << "\t" << fpp << "\t" << actual << "\t" << bl.length() << "\t" << byte_per_insert
+               << "\t" << bf.density() << "\t" << bf.approx_unique_element_count() << std::endl;
       ASSERT_TRUE(actual < fpp * 10);
       ASSERT_TRUE(actual > fpp / 10);
     }