blob: 5739494e8ddfa9b8f97b56e7f42d9ce8f959114e [file] [log] [blame]
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// 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).
#include "table/full_filter_block.h"
#include "monitoring/perf_context_imp.h"
#include "port/port.h"
#include "rocksdb/filter_policy.h"
#include "util/coding.h"
namespace rocksdb {
FullFilterBlockBuilder::FullFilterBlockBuilder(
const SliceTransform* prefix_extractor, bool whole_key_filtering,
FilterBitsBuilder* filter_bits_builder)
: prefix_extractor_(prefix_extractor),
whole_key_filtering_(whole_key_filtering),
num_added_(0) {
assert(filter_bits_builder != nullptr);
filter_bits_builder_.reset(filter_bits_builder);
}
void FullFilterBlockBuilder::Add(const Slice& key) {
if (whole_key_filtering_) {
AddKey(key);
}
if (prefix_extractor_ && prefix_extractor_->InDomain(key)) {
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);
AddKey(prefix);
}
Slice FullFilterBlockBuilder::Finish(const BlockHandle& tmp, Status* status) {
// In this impl we ignore BlockHandle
*status = Status::OK();
if (num_added_ != 0) {
num_added_ = 0;
return filter_bits_builder_->Finish(&filter_data_);
}
return Slice();
}
FullFilterBlockReader::FullFilterBlockReader(
const SliceTransform* prefix_extractor, bool _whole_key_filtering,
const Slice& contents, FilterBitsReader* filter_bits_reader,
Statistics* stats)
: FilterBlockReader(contents.size(), stats, _whole_key_filtering),
prefix_extractor_(prefix_extractor),
contents_(contents) {
assert(filter_bits_reader != nullptr);
filter_bits_reader_.reset(filter_bits_reader);
}
FullFilterBlockReader::FullFilterBlockReader(
const SliceTransform* prefix_extractor, bool _whole_key_filtering,
BlockContents&& contents, FilterBitsReader* filter_bits_reader,
Statistics* stats)
: FullFilterBlockReader(prefix_extractor, _whole_key_filtering,
contents.data, filter_bits_reader, stats) {
block_contents_ = std::move(contents);
}
bool FullFilterBlockReader::KeyMayMatch(const Slice& key, uint64_t block_offset,
const bool no_io,
const Slice* const const_ikey_ptr) {
assert(block_offset == kNotValid);
if (!whole_key_filtering_) {
return true;
}
return MayMatch(key);
}
bool FullFilterBlockReader::PrefixMayMatch(const Slice& prefix,
uint64_t block_offset,
const bool no_io,
const Slice* const const_ikey_ptr) {
assert(block_offset == kNotValid);
if (!prefix_extractor_) {
return true;
}
return MayMatch(prefix);
}
bool FullFilterBlockReader::MayMatch(const Slice& entry) {
if (contents_.size() != 0) {
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;
}
}
return true; // remain the same with block_based filter
}
size_t FullFilterBlockReader::ApproximateMemoryUsage() const {
return contents_.size();
}
} // namespace rocksdb