@ -3,6 +3,8 @@
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
# include <set>
# include "table/block_based/full_filter_block.h"
# include "rocksdb/filter_policy.h"
# include "table/block_based/block_based_table_reader.h"
@ -205,24 +207,62 @@ TEST_F(FullFilterBlockTest, EmptyBuilder) {
/*lookup_context=*/ nullptr ) ) ;
}
class CountUniqueFilterBitsBuilderWrapper : public FilterBitsBuilder {
std : : unique_ptr < FilterBitsBuilder > b_ ;
std : : set < std : : string > uniq_ ;
public :
explicit CountUniqueFilterBitsBuilderWrapper ( FilterBitsBuilder * b ) : b_ ( b ) { }
~ CountUniqueFilterBitsBuilderWrapper ( ) override { }
void AddKey ( const Slice & key ) override {
b_ - > AddKey ( key ) ;
uniq_ . insert ( key . ToString ( ) ) ;
}
Slice Finish ( std : : unique_ptr < const char [ ] > * buf ) override {
Slice rv = b_ - > Finish ( buf ) ;
uniq_ . clear ( ) ;
return rv ;
}
int CalculateNumEntry ( const uint32_t bytes ) override {
return b_ - > CalculateNumEntry ( bytes ) ;
}
size_t CountUnique ( ) { return uniq_ . size ( ) ; }
} ;
TEST_F ( FullFilterBlockTest , DuplicateEntries ) {
{ // empty prefixes
std : : unique_ptr < const SliceTransform > prefix_extractor (
NewFixedPrefixTransform ( 0 ) ) ;
auto bits_builder = dynamic_cast < FullFilterBitsBuilder * > (
auto bits_builder = new CountUniqueFilterBitsBuilderWrapper (
table_options_ . filter_policy - > GetFilterBitsBuilder ( ) ) ;
const bool WHOLE_KEY = true ;
FullFilterBlockBuilder builder ( prefix_extractor . get ( ) , WHOLE_KEY ,
bits_builder ) ;
ASSERT_EQ ( 0 , builder . NumAdded ( ) ) ;
builder . Add ( " key " ) ; // test with empty prefix
ASSERT_EQ ( 2 , bits_builder - > hash_entries_ . size ( ) ) ;
ASSERT_EQ ( 0 , bits_builder - > CountUnique ( ) ) ;
// adds key and empty prefix; both abstractions count them
builder . Add ( " key1 " ) ;
ASSERT_EQ ( 2 , builder . NumAdded ( ) ) ;
ASSERT_EQ ( 2 , bits_builder - > CountUnique ( ) ) ;
// Add different key (unique) and also empty prefix (not unique).
// From here in this test, it's immaterial whether the block builder
// can count unique keys.
builder . Add ( " key2 " ) ;
ASSERT_EQ ( 3 , bits_builder - > CountUnique ( ) ) ;
// Empty key -> nothing unique
builder . Add ( " " ) ;
ASSERT_EQ ( 3 , bits_builder - > CountUnique ( ) ) ;
}
// mix of empty and non-empty
std : : unique_ptr < const SliceTransform > prefix_extractor (
NewFixedPrefixTransform ( 7 ) ) ;
auto bits_builder = dynamic_cast < FullFilterBitsBuilder * > (
auto bits_builder = new CountUniqueFilterBitsBuilderWrapper (
table_options_ . filter_policy - > GetFilterBitsBuilder ( ) ) ;
const bool WHOLE_KEY = true ;
FullFilterBlockBuilder builder ( prefix_extractor . get ( ) , WHOLE_KEY ,
@ -234,8 +274,8 @@ TEST_F(FullFilterBlockTest, DuplicateEntries) {
builder . Add ( " prefix1key2 " ) ;
builder . Add ( " prefix1key3 " ) ;
builder . Add ( " prefix2key4 " ) ;
// two prefix adn 4 keys
ASSERT_EQ ( 1 + 2 + 4 , bits_builder - > hash_entries_ . siz e( ) ) ;
// 1 empty, 2 non-empty prefixes, and 4 non-empty keys
ASSERT_EQ ( 1 + 2 + 4 , bits_builder - > CountUniqu e( ) ) ;
}
TEST_F ( FullFilterBlockTest , SingleChunk ) {