@ -20,8 +20,10 @@
# include "cache/cache_reservation_manager.h"
# include "logging/logging.h"
# include "port/lang.h"
# include "rocksdb/convenience.h"
# include "rocksdb/rocksdb_namespace.h"
# include "rocksdb/slice.h"
# include "rocksdb/utilities/object_registry.h"
# include "table/block_based/block_based_filter_block.h"
# include "table/block_based/block_based_table_reader.h"
# include "table/block_based/filter_policy_internal.h"
@ -1311,6 +1313,18 @@ Status XXPH3FilterBitsBuilder::MaybePostVerify(const Slice& filter_content) {
}
} // namespace
const char * BuiltinFilterPolicy : : kClassName ( ) {
return " rocksdb.internal.BuiltinFilter " ;
}
bool BuiltinFilterPolicy : : IsInstanceOf ( const std : : string & name ) const {
if ( name = = kClassName ( ) ) {
return true ;
} else {
return FilterPolicy : : IsInstanceOf ( name ) ;
}
}
BloomLikeFilterPolicy : : BloomLikeFilterPolicy ( double bits_per_key )
: warned_ ( false ) , aggregate_rounding_balance_ ( 0 ) {
// Sanitize bits_per_key
@ -1345,17 +1359,28 @@ BloomLikeFilterPolicy::BloomLikeFilterPolicy(double bits_per_key)
}
BloomLikeFilterPolicy : : ~ BloomLikeFilterPolicy ( ) { }
const char * BloomLikeFilterPolicy : : kClassName ( ) {
return " rocksdb.internal.BloomLikeFilter " ;
}
bool BloomLikeFilterPolicy : : IsInstanceOf ( const std : : string & name ) const {
if ( name = = kClassName ( ) ) {
return true ;
} else {
return BuiltinFilterPolicy : : IsInstanceOf ( name ) ;
}
}
const char * BuiltinFilterPolicy : : Name ( ) const {
const char * ReadOnly BuiltinFilterPolicy: : kClass Name( ) {
return " rocksdb.BuiltinBloomFilter " ;
}
const char * DeprecatedBlockBasedBloomFilterPolicy : : kName ( ) {
const char * DeprecatedBlockBasedBloomFilterPolicy : : kClass Name ( ) {
return " rocksdb.internal.DeprecatedBlockBasedBloomFilter " ;
}
std : : string DeprecatedBlockBasedBloomFilterPolicy : : GetId ( ) const {
return kName ( ) + GetBitsPerKeySuffix ( ) ;
std : : string BloomLike FilterPolicy : : GetId ( ) const {
return Name ( ) + GetBitsPerKeySuffix ( ) ;
}
DeprecatedBlockBasedBloomFilterPolicy : : DeprecatedBlockBasedBloomFilterPolicy (
@ -1446,12 +1471,13 @@ FilterBitsBuilder* BloomFilterPolicy::GetBuilderWithContext(
}
}
const char * BloomFilterPolicy : : kName ( ) { return " bloomfilter " ; }
const char * BloomFilterPolicy : : kClassName ( ) { return " bloomfilter " ; }
const char * BloomFilterPolicy : : kNickName ( ) { return " rocksdb.BloomFilter " ; }
std : : string BloomFilterPolicy : : GetId ( ) const {
// Including ":false" for better forward-compatibility with 6.29 and earlier
// which required a boolean `use_block_based_builder` parameter
return kName ( ) + GetBitsPerKeySuffix ( ) + " :false " ;
return BloomLikeFilterPolicy : : GetId ( ) + " :false " ;
}
FilterBitsBuilder * BloomLikeFilterPolicy : : GetFastLocalBloomBuilderWithContext (
@ -1543,14 +1569,10 @@ FilterBitsBuilder* BuiltinFilterPolicy::GetBuilderFromContext(
// For testing only, but always constructable with internal names
namespace test {
const char * LegacyBloomFilterPolicy : : kName ( ) {
const char * LegacyBloomFilterPolicy : : kClass Name ( ) {
return " rocksdb.internal.LegacyBloomFilter " ;
}
std : : string LegacyBloomFilterPolicy : : GetId ( ) const {
return kName ( ) + GetBitsPerKeySuffix ( ) ;
}
FilterBitsBuilder * LegacyBloomFilterPolicy : : GetBuilderWithContext (
const FilterBuildingContext & context ) const {
if ( GetMillibitsPerKey ( ) = = 0 ) {
@ -1560,14 +1582,10 @@ FilterBitsBuilder* LegacyBloomFilterPolicy::GetBuilderWithContext(
return GetLegacyBloomBuilderWithContext ( context ) ;
}
const char * FastLocalBloomFilterPolicy : : kName ( ) {
const char * FastLocalBloomFilterPolicy : : kClass Name ( ) {
return " rocksdb.internal.FastLocalBloomFilter " ;
}
std : : string FastLocalBloomFilterPolicy : : GetId ( ) const {
return kName ( ) + GetBitsPerKeySuffix ( ) ;
}
FilterBitsBuilder * FastLocalBloomFilterPolicy : : GetBuilderWithContext (
const FilterBuildingContext & context ) const {
if ( GetMillibitsPerKey ( ) = = 0 ) {
@ -1577,14 +1595,10 @@ FilterBitsBuilder* FastLocalBloomFilterPolicy::GetBuilderWithContext(
return GetFastLocalBloomBuilderWithContext ( context ) ;
}
const char * Standard128RibbonFilterPolicy : : kName ( ) {
const char * Standard128RibbonFilterPolicy : : kClass Name ( ) {
return " rocksdb.internal.Standard128RibbonFilter " ;
}
std : : string Standard128RibbonFilterPolicy : : GetId ( ) const {
return kName ( ) + GetBitsPerKeySuffix ( ) ;
}
FilterBitsBuilder * Standard128RibbonFilterPolicy : : GetBuilderWithContext (
const FilterBuildingContext & context ) const {
if ( GetMillibitsPerKey ( ) = = 0 ) {
@ -1816,10 +1830,11 @@ FilterBitsBuilder* RibbonFilterPolicy::GetBuilderWithContext(
}
}
const char * RibbonFilterPolicy : : kName ( ) { return " ribbonfilter " ; }
const char * RibbonFilterPolicy : : kClassName ( ) { return " ribbonfilter " ; }
const char * RibbonFilterPolicy : : kNickName ( ) { return " rocksdb.RibbonFilter " ; }
std : : string RibbonFilterPolicy : : GetId ( ) const {
return kName ( ) + GetBitsPerKeySuffix ( ) + " : " +
return BloomLikeFilterPolicy : : GetId ( ) + " : " +
ROCKSDB_NAMESPACE : : ToString ( bloom_before_level_ ) ;
}
@ -1837,19 +1852,19 @@ FilterPolicy::~FilterPolicy() { }
std : : shared_ptr < const FilterPolicy > BloomLikeFilterPolicy : : Create (
const std : : string & name , double bits_per_key ) {
if ( name = = test : : LegacyBloomFilterPolicy : : kName ( ) ) {
if ( name = = test : : LegacyBloomFilterPolicy : : kClass Name ( ) ) {
return std : : make_shared < test : : LegacyBloomFilterPolicy > ( bits_per_key ) ;
} else if ( name = = test : : FastLocalBloomFilterPolicy : : kName ( ) ) {
} else if ( name = = test : : FastLocalBloomFilterPolicy : : kClass Name ( ) ) {
return std : : make_shared < test : : FastLocalBloomFilterPolicy > ( bits_per_key ) ;
} else if ( name = = test : : Standard128RibbonFilterPolicy : : kName ( ) ) {
} else if ( name = = test : : Standard128RibbonFilterPolicy : : kClass Name ( ) ) {
return std : : make_shared < test : : Standard128RibbonFilterPolicy > ( bits_per_key ) ;
} else if ( name = = DeprecatedBlockBasedBloomFilterPolicy : : kName ( ) ) {
} else if ( name = = DeprecatedBlockBasedBloomFilterPolicy : : kClass Name ( ) ) {
return std : : make_shared < DeprecatedBlockBasedBloomFilterPolicy > (
bits_per_key ) ;
} else if ( name = = BloomFilterPolicy : : kName ( ) ) {
} else if ( name = = BloomFilterPolicy : : kClass Name ( ) ) {
// For testing
return std : : make_shared < BloomFilterPolicy > ( bits_per_key ) ;
} else if ( name = = RibbonFilterPolicy : : kName ( ) ) {
} else if ( name = = RibbonFilterPolicy : : kClass Name ( ) ) {
// For testing
return std : : make_shared < RibbonFilterPolicy > ( bits_per_key ,
/*bloom_before_level*/ 0 ) ;
@ -1858,59 +1873,173 @@ std::shared_ptr<const FilterPolicy> BloomLikeFilterPolicy::Create(
}
}
# ifndef ROCKSDB_LITE
namespace {
static ObjectLibrary : : PatternEntry FilterPatternEntryWithBits (
const char * name ) {
return ObjectLibrary : : PatternEntry ( name , false ) . AddNumber ( " : " , false ) ;
}
template < typename T >
T * NewBuiltinFilterPolicyWithBits ( const std : : string & uri ) {
const std : : vector < std : : string > vals = StringSplit ( uri , ' : ' ) ;
double bits_per_key = ParseDouble ( vals [ 1 ] ) ;
return new T ( bits_per_key ) ;
}
static int RegisterBuiltinFilterPolicies ( ObjectLibrary & library ,
const std : : string & /*arg*/ ) {
library . AddFactory < const FilterPolicy > (
ReadOnlyBuiltinFilterPolicy : : kClassName ( ) ,
[ ] ( const std : : string & /*uri*/ , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset ( new ReadOnlyBuiltinFilterPolicy ( ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits ( BloomFilterPolicy : : kClassName ( ) )
. AnotherName ( BloomFilterPolicy : : kNickName ( ) ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset ( NewBuiltinFilterPolicyWithBits < BloomFilterPolicy > ( uri ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits ( BloomFilterPolicy : : kClassName ( ) )
. AnotherName ( BloomFilterPolicy : : kNickName ( ) )
. AddSuffix ( " :false " ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset ( NewBuiltinFilterPolicyWithBits < BloomFilterPolicy > ( uri ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits ( BloomFilterPolicy : : kClassName ( ) )
. AnotherName ( BloomFilterPolicy : : kNickName ( ) )
. AddSuffix ( " :true " ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
const std : : vector < std : : string > vals = StringSplit ( uri , ' : ' ) ;
double bits_per_key = ParseDouble ( vals [ 1 ] ) ;
// NOTE: This case previously configured the deprecated block-based
// filter, but old ways of configuring that now map to full filter. We
// defer to the corresponding API to ensure consistency in case that
// change is reverted.
guard - > reset ( NewBloomFilterPolicy ( bits_per_key , true ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits ( RibbonFilterPolicy : : kClassName ( ) )
. AnotherName ( RibbonFilterPolicy : : kNickName ( ) ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
const std : : vector < std : : string > vals = StringSplit ( uri , ' : ' ) ;
double bits_per_key = ParseDouble ( vals [ 1 ] ) ;
guard - > reset ( NewRibbonFilterPolicy ( bits_per_key ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits ( RibbonFilterPolicy : : kClassName ( ) )
. AnotherName ( RibbonFilterPolicy : : kNickName ( ) )
. AddNumber ( " : " , true ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
const std : : vector < std : : string > vals = StringSplit ( uri , ' : ' ) ;
double bits_per_key = ParseDouble ( vals [ 1 ] ) ;
int bloom_before_level = ParseInt ( vals [ 2 ] ) ;
guard - > reset ( NewRibbonFilterPolicy ( bits_per_key , bloom_before_level ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits ( test : : LegacyBloomFilterPolicy : : kClassName ( ) ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset (
NewBuiltinFilterPolicyWithBits < test : : LegacyBloomFilterPolicy > ( uri ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits (
test : : FastLocalBloomFilterPolicy : : kClassName ( ) ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset (
NewBuiltinFilterPolicyWithBits < test : : FastLocalBloomFilterPolicy > (
uri ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits (
test : : Standard128RibbonFilterPolicy : : kClassName ( ) ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset (
NewBuiltinFilterPolicyWithBits < test : : Standard128RibbonFilterPolicy > (
uri ) ) ;
return guard - > get ( ) ;
} ) ;
library . AddFactory < const FilterPolicy > (
FilterPatternEntryWithBits (
DeprecatedBlockBasedBloomFilterPolicy : : kClassName ( ) ) ,
[ ] ( const std : : string & uri , std : : unique_ptr < const FilterPolicy > * guard ,
std : : string * /* errmsg */ ) {
guard - > reset ( NewBuiltinFilterPolicyWithBits <
DeprecatedBlockBasedBloomFilterPolicy > ( uri ) ) ;
return guard - > get ( ) ;
} ) ;
size_t num_types ;
return static_cast < int > ( library . GetFactoryCount ( & num_types ) ) ;
}
} // namespace
# endif // ROCKSDB_LITE
Status FilterPolicy : : CreateFromString (
const ConfigOptions & /*options*/ , const std : : string & value ,
const ConfigOptions & options , const std : : string & value ,
std : : shared_ptr < const FilterPolicy > * policy ) {
if ( value = = kNullptrString ) {
if ( value = = kNullptrString | | value . empty ( ) ) {
policy - > reset ( ) ;
return Status : : OK ( ) ;
} else if ( value = = " rocksdb.BuiltinBloomFilter " ) {
} else if ( value = = ReadOnlyBuiltinFilterPolicy : : kClassName ( ) ) {
* policy = std : : make_shared < ReadOnlyBuiltinFilterPolicy > ( ) ;
return Status : : OK ( ) ;
}
# ifndef ROCKSDB_LITE
const std : : vector < std : : string > vals = StringSplit ( value , ' : ' ) ;
if ( vals . size ( ) < 2 ) {
return Status : : NotFound ( " Invalid filter policy name " , value ) ;
}
const std : : string & name = vals [ 0 ] ;
double bits_per_key = ParseDouble ( trim ( vals [ 1 ] ) ) ;
if ( name = = BloomFilterPolicy : : kName ( ) ) {
bool use_block_based_builder = false ;
if ( vals . size ( ) > 2 ) {
use_block_based_builder =
ParseBoolean ( " use_block_based_builder " , trim ( vals [ 2 ] ) ) ;
}
policy - > reset ( NewBloomFilterPolicy ( bits_per_key , use_block_based_builder ) ) ;
} else if ( name = = RibbonFilterPolicy : : kName ( ) ) {
int bloom_before_level ;
if ( vals . size ( ) < 3 ) {
bloom_before_level = 0 ;
} else {
bloom_before_level = ParseInt ( trim ( vals [ 2 ] ) ) ;
}
policy - > reset ( NewRibbonFilterPolicy ( /*bloom_equivalent*/ bits_per_key ,
bloom_before_level ) ) ;
std : : string id ;
std : : unordered_map < std : : string , std : : string > opt_map ;
Status status =
Customizable : : GetOptionsMap ( options , policy - > get ( ) , value , & id , & opt_map ) ;
if ( ! status . ok ( ) ) { // GetOptionsMap failed
return status ;
} else if ( id . empty ( ) ) { // We have no Id but have options. Not good
return Status : : NotSupported ( " Cannot reset object " , id ) ;
} else {
* policy = BloomLikeFilterPolicy : : Create ( name , bits_per_key ) ;
# ifndef ROCKSDB_LITE
static std : : once_flag loaded ;
std : : call_once ( loaded , [ & ] ( ) {
RegisterBuiltinFilterPolicies ( * ( ObjectLibrary : : Default ( ) . get ( ) ) , " " ) ;
} ) ;
status = options . registry - > NewSharedObject ( id , policy ) ;
# else
status =
Status : : NotSupported ( " Cannot load filter policy in LITE mode " , value ) ;
# endif // ROCKSDB_LITE
}
if ( * policy ) {
if ( options . ignore_unsupported_options & & status . IsNotSupported ( ) ) {
return Status : : OK ( ) ;
} else {
return Status : : NotFound ( " Invalid filter policy name " , value ) ;
} else if ( status . ok ( ) ) {
status = Customizable : : ConfigureNewObject (
options , const_cast < FilterPolicy * > ( policy - > get ( ) ) , opt_map ) ;
}
# else
return Status : : NotSupported ( " Cannot load filter policy in LITE mode " , value ) ;
# endif // ROCKSDB_LITE
return status ;
}
const std : : vector < std : : string > & BloomLikeFilterPolicy : : GetAllFixedImpls ( ) {
STATIC_AVOID_DESTRUCTION ( std : : vector < std : : string > , impls ) {
// Match filter_bench -impl=x ordering
test : : LegacyBloomFilterPolicy : : kName ( ) ,
DeprecatedBlockBasedBloomFilterPolicy : : kName ( ) ,
test : : FastLocalBloomFilterPolicy : : kName ( ) ,
test : : Standard128RibbonFilterPolicy : : kName ( ) ,
test : : LegacyBloomFilterPolicy : : kClass Name ( ) ,
DeprecatedBlockBasedBloomFilterPolicy : : kClass Name ( ) ,
test : : FastLocalBloomFilterPolicy : : kClass Name ( ) ,
test : : Standard128RibbonFilterPolicy : : kClass Name ( ) ,
} ;
return impls ;
}