2016-02-10 00:12:00 +01:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-16 01:03:42 +02:00
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
2014-09-08 19:37:05 +02:00
|
|
|
|
|
|
|
#include "table/full_filter_block.h"
|
|
|
|
|
2017-04-06 04:02:00 +02:00
|
|
|
#include "monitoring/perf_context_imp.h"
|
2014-09-08 19:37:05 +02:00
|
|
|
#include "port/port.h"
|
2017-04-06 04:02:00 +02:00
|
|
|
#include "rocksdb/filter_policy.h"
|
2014-09-08 19:37:05 +02:00
|
|
|
#include "util/coding.h"
|
|
|
|
|
|
|
|
namespace rocksdb {
|
|
|
|
|
|
|
|
FullFilterBlockBuilder::FullFilterBlockBuilder(
|
2015-02-05 02:03:57 +01:00
|
|
|
const SliceTransform* prefix_extractor, bool whole_key_filtering,
|
2014-09-08 19:37:05 +02:00
|
|
|
FilterBitsBuilder* filter_bits_builder)
|
|
|
|
: prefix_extractor_(prefix_extractor),
|
2015-02-05 02:03:57 +01:00
|
|
|
whole_key_filtering_(whole_key_filtering),
|
2014-09-08 19:37:05 +02:00
|
|
|
num_added_(0) {
|
|
|
|
assert(filter_bits_builder != nullptr);
|
|
|
|
filter_bits_builder_.reset(filter_bits_builder);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FullFilterBlockBuilder::Add(const Slice& key) {
|
2018-04-24 19:53:38 +02:00
|
|
|
const bool add_prefix = prefix_extractor_ && prefix_extractor_->InDomain(key);
|
2014-09-08 19:37:05 +02:00
|
|
|
if (whole_key_filtering_) {
|
2018-04-24 19:53:38 +02:00
|
|
|
if (!add_prefix) {
|
|
|
|
AddKey(key);
|
|
|
|
} else {
|
|
|
|
// if both whole_key and prefix are added to bloom then we will have whole
|
|
|
|
// key and prefix addition being interleaved and thus cannot rely on the
|
|
|
|
// bits builder to properly detect the duplicates by comparing with the
|
|
|
|
// last item.
|
|
|
|
Slice last_whole_key = Slice(last_whole_key_str_);
|
|
|
|
if (last_whole_key.compare(key) != 0) {
|
|
|
|
AddKey(key);
|
|
|
|
last_whole_key_str_ = key.ToString();
|
|
|
|
}
|
|
|
|
}
|
2014-09-08 19:37:05 +02:00
|
|
|
}
|
2018-04-24 19:53:38 +02:00
|
|
|
if (add_prefix) {
|
2014-09-08 19:37:05 +02:00
|
|
|
AddPrefix(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add key to filter if needed
|
|
|
|
inline void FullFilterBlockBuilder::AddKey(const Slice& key) {
|
|
|
|
filter_bits_builder_->AddKey(key);
|
|
|
|
num_added_++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add prefix to filter if needed
|
|
|
|
inline void FullFilterBlockBuilder::AddPrefix(const Slice& key) {
|
|
|
|
Slice prefix = prefix_extractor_->Transform(key);
|
2018-04-24 19:53:38 +02:00
|
|
|
if (whole_key_filtering_) {
|
|
|
|
// if both whole_key and prefix are added to bloom then we will have whole
|
|
|
|
// key and prefix addition being interleaved and thus cannot rely on the
|
|
|
|
// bits builder to properly detect the duplicates by comparing with the last
|
|
|
|
// item.
|
|
|
|
Slice last_prefix = Slice(last_prefix_str_);
|
|
|
|
if (last_prefix.compare(prefix) != 0) {
|
|
|
|
AddKey(prefix);
|
|
|
|
last_prefix_str_ = prefix.ToString();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
AddKey(prefix);
|
|
|
|
}
|
2014-09-08 19:37:05 +02:00
|
|
|
}
|
|
|
|
|
2018-03-05 22:08:17 +01:00
|
|
|
Slice FullFilterBlockBuilder::Finish(const BlockHandle& /*tmp*/,
|
|
|
|
Status* status) {
|
2017-03-07 22:48:02 +01:00
|
|
|
// In this impl we ignore BlockHandle
|
|
|
|
*status = Status::OK();
|
2014-09-08 19:37:05 +02:00
|
|
|
if (num_added_ != 0) {
|
|
|
|
num_added_ = 0;
|
2014-09-16 19:30:32 +02:00
|
|
|
return filter_bits_builder_->Finish(&filter_data_);
|
2014-09-08 19:37:05 +02:00
|
|
|
}
|
|
|
|
return Slice();
|
|
|
|
}
|
|
|
|
|
|
|
|
FullFilterBlockReader::FullFilterBlockReader(
|
2016-06-10 00:48:45 +02:00
|
|
|
const SliceTransform* prefix_extractor, bool _whole_key_filtering,
|
2016-06-03 19:47:47 +02:00
|
|
|
const Slice& contents, FilterBitsReader* filter_bits_reader,
|
|
|
|
Statistics* stats)
|
2016-06-10 00:48:45 +02:00
|
|
|
: FilterBlockReader(contents.size(), stats, _whole_key_filtering),
|
2016-06-03 19:47:47 +02:00
|
|
|
prefix_extractor_(prefix_extractor),
|
2014-09-08 19:37:05 +02:00
|
|
|
contents_(contents) {
|
|
|
|
assert(filter_bits_reader != nullptr);
|
|
|
|
filter_bits_reader_.reset(filter_bits_reader);
|
2014-08-16 00:05:09 +02:00
|
|
|
}
|
2014-09-08 19:37:05 +02:00
|
|
|
|
2014-08-16 00:05:09 +02:00
|
|
|
FullFilterBlockReader::FullFilterBlockReader(
|
2016-06-10 00:48:45 +02:00
|
|
|
const SliceTransform* prefix_extractor, bool _whole_key_filtering,
|
2016-06-03 19:47:47 +02:00
|
|
|
BlockContents&& contents, FilterBitsReader* filter_bits_reader,
|
|
|
|
Statistics* stats)
|
2016-06-10 00:48:45 +02:00
|
|
|
: FullFilterBlockReader(prefix_extractor, _whole_key_filtering,
|
2016-06-03 19:47:47 +02:00
|
|
|
contents.data, filter_bits_reader, stats) {
|
2014-08-16 00:05:09 +02:00
|
|
|
block_contents_ = std::move(contents);
|
2014-09-08 19:37:05 +02:00
|
|
|
}
|
|
|
|
|
2017-03-22 17:11:23 +01:00
|
|
|
bool FullFilterBlockReader::KeyMayMatch(const Slice& key, uint64_t block_offset,
|
2018-03-05 22:08:17 +01:00
|
|
|
const bool /*no_io*/,
|
|
|
|
const Slice* const /*const_ikey_ptr*/) {
|
2018-04-13 02:55:14 +02:00
|
|
|
#ifdef NDEBUG
|
|
|
|
(void)block_offset;
|
|
|
|
#endif
|
2014-09-08 19:37:05 +02:00
|
|
|
assert(block_offset == kNotValid);
|
|
|
|
if (!whole_key_filtering_) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return MayMatch(key);
|
|
|
|
}
|
|
|
|
|
2018-03-05 22:08:17 +01:00
|
|
|
bool FullFilterBlockReader::PrefixMayMatch(
|
|
|
|
const Slice& prefix, uint64_t block_offset, const bool /*no_io*/,
|
|
|
|
const Slice* const /*const_ikey_ptr*/) {
|
2018-04-13 02:55:14 +02:00
|
|
|
#ifdef NDEBUG
|
|
|
|
(void)block_offset;
|
|
|
|
#endif
|
2014-09-08 19:37:05 +02:00
|
|
|
assert(block_offset == kNotValid);
|
|
|
|
if (!prefix_extractor_) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return MayMatch(prefix);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FullFilterBlockReader::MayMatch(const Slice& entry) {
|
|
|
|
if (contents_.size() != 0) {
|
2015-10-07 20:23:20 +02:00
|
|
|
if (filter_bits_reader_->MayMatch(entry)) {
|
|
|
|
PERF_COUNTER_ADD(bloom_sst_hit_count, 1);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
PERF_COUNTER_ADD(bloom_sst_miss_count, 1);
|
|
|
|
return false;
|
|
|
|
}
|
2014-09-08 19:37:05 +02:00
|
|
|
}
|
|
|
|
return true; // remain the same with block_based filter
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t FullFilterBlockReader::ApproximateMemoryUsage() const {
|
|
|
|
return contents_.size();
|
|
|
|
}
|
|
|
|
} // namespace rocksdb
|