diff options
author | Sage Weil <sage@inktank.com> | 2013-09-18 20:07:01 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-09-19 18:25:18 -0700 |
commit | 6a8b4a9c918329e6ce92f2cc084559165d1a37e0 (patch) | |
tree | be50a594a0a7cf79ff51c8bcf5c3027e77685000 | |
parent | 3310404d2d9588497236eb0ff174702b60e91e86 (diff) | |
download | ceph-6a8b4a9c918329e6ce92f2cc084559165d1a37e0.tar.gz |
common/bloom_filter: make bloom_filter encodable
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/common/Makefile.am | 3 | ||||
-rw-r--r-- | src/common/bloom_filter.cc | 76 | ||||
-rw-r--r-- | src/include/bloom_filter.hpp | 27 | ||||
-rw-r--r-- | src/test/encoding/types.h | 3 |
4 files changed, 104 insertions, 5 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 4c027909b4d..43fc0f998be 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -65,7 +65,8 @@ libcommon_la_SOURCES = \ common/ceph_strings.cc \ common/ceph_frag.cc \ common/addr_parsing.c \ - common/hobject.cc + common/hobject.cc \ + common/bloom_filter.cc # these should go out of libcommon libcommon_la_SOURCES += \ diff --git a/src/common/bloom_filter.cc b/src/common/bloom_filter.cc new file mode 100644 index 00000000000..f602b80149e --- /dev/null +++ b/src/common/bloom_filter.cc @@ -0,0 +1,76 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "include/types.h" +#include "common/bloom_filter.hpp" + +void bloom_filter::encode(bufferlist& bl) const +{ + ENCODE_START(1, 1, bl); + ::encode((uint64_t)salt_count_, bl); + ::encode((uint64_t)table_size_, bl); + ::encode((uint64_t)inserted_element_count_, bl); + ::encode((uint64_t)random_seed_, bl); + bufferptr bp((const char*)bit_table_, raw_table_size_); + ::encode(bp, bl); + ENCODE_FINISH(bl); +} + +void bloom_filter::decode(bufferlist::iterator& p) +{ + DECODE_START(1, p); + uint64_t v; + ::decode(v, p); + salt_count_ = v; + ::decode(v, p); + table_size_ = v; + ::decode(v, p); + inserted_element_count_ = v; + ::decode(v, p); + random_seed_ = v; + bufferlist t; + ::decode(t, p); + + salt_.clear(); + generate_unique_salt(); + raw_table_size_ = t.length(); + assert(raw_table_size_ == table_size_ / bits_per_char); + delete bit_table_; + bit_table_ = new cell_type[raw_table_size_]; + t.copy(0, raw_table_size_, (char *)bit_table_); + + DECODE_FINISH(p); +} + +void bloom_filter::dump(Formatter *f) const +{ + f->dump_unsigned("salt_count", salt_count_); + f->dump_unsigned("table_size", table_size_); + f->dump_unsigned("raw_table_size", raw_table_size_); + f->dump_unsigned("insert_count", inserted_element_count_); + f->dump_unsigned("random_seed", random_seed_); + + f->open_array_section("salt_table"); + for (std::vector<bloom_type>::const_iterator i = salt_.begin(); i != salt_.end(); ++i) + f->dump_unsigned("salt", *i); + f->close_section(); + + f->open_array_section("bit_table"); + for (unsigned i = 0; i < raw_table_size_; ++i) + f->dump_unsigned("byte", (unsigned)bit_table_[i]); + f->close_section(); +} + +void bloom_filter::generate_test_instances(list<bloom_filter*>& ls) +{ + ls.push_back(new bloom_filter(10, .5, 1)); + ls.push_back(new bloom_filter(10, .5, 1)); + ls.back()->insert("foo"); + ls.back()->insert("bar"); + ls.push_back(new bloom_filter(50, .5, 1)); + ls.back()->insert("foo"); + ls.back()->insert("bar"); + ls.back()->insert("baz"); + ls.back()->insert("boof"); + ls.back()->insert("boogggg"); +} diff --git a/src/include/bloom_filter.hpp b/src/include/bloom_filter.hpp index 59dafc9b5f7..a65543c88ed 100644 --- a/src/include/bloom_filter.hpp +++ b/src/include/bloom_filter.hpp @@ -29,6 +29,8 @@ #include <string> #include <vector> +#include "include/encoding.h" +#include "common/Formatter.h" static const std::size_t bits_per_char = 0x08; // 8 bits in 1 char(unsigned) static const unsigned char bit_mask[bits_per_char] = { @@ -52,6 +54,15 @@ protected: public: + bloom_filter() + : bit_table_(0), + salt_count_(0), + table_size_(0), + raw_table_size_(0), + inserted_element_count_(0), + random_seed_(0) + {} + bloom_filter(const std::size_t& predicted_inserted_element_count, const double& false_positive_probability, const std::size_t& random_seed) @@ -61,10 +72,7 @@ public: { find_optimal_parameters(predicted_inserted_element_count, false_positive_probability, &salt_count_, &table_size_); - generate_unique_salt(); - raw_table_size_ = table_size_ / bits_per_char; - bit_table_ = new cell_type[raw_table_size_]; - std::fill_n(bit_table_,raw_table_size_,0x00); + init(); } bloom_filter(const std::size_t& salt_count, std::size_t table_size, @@ -75,6 +83,10 @@ public: inserted_element_count_(0), random_seed_((random_seed) ? random_seed : 0xA5A5A5A5) { + init(); + } + + void init() { generate_unique_salt(); raw_table_size_ = table_size_ / bits_per_char; bit_table_ = new cell_type[raw_table_size_]; @@ -453,7 +465,14 @@ protected: std::size_t raw_table_size_; std::size_t inserted_element_count_; std::size_t random_seed_; + +public: + void encode(bufferlist& bl) const; + void decode(bufferlist::iterator& bl); + void dump(Formatter *f) const; + static void generate_test_instances(list<bloom_filter*>& ls); }; +WRITE_CLASS_ENCODER(bloom_filter) inline bloom_filter operator & (const bloom_filter& a, const bloom_filter& b) { diff --git a/src/test/encoding/types.h b/src/test/encoding/types.h index fe17f077d8e..dd1ea4d570c 100644 --- a/src/test/encoding/types.h +++ b/src/test/encoding/types.h @@ -4,6 +4,9 @@ TYPE(CompatSet) #include "include/filepath.h" TYPE(filepath) +#include "include/bloom_filter.hpp" +TYPE(bloom_filter) + #include "common/snap_types.h" TYPE(SnapContext) TYPE(SnapRealmInfo) |