// 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). #pragma once #include #include #include #include "db/dbformat.h" #include "rocksdb/options.h" #include "rocksdb/slice.h" #include "rocksdb/slice_transform.h" #include "table/block.h" #include "table/block_based_table_reader.h" #include "table/full_filter_block.h" #include "table/index_builder.h" #include "util/autovector.h" namespace rocksdb { class PartitionedFilterBlockBuilder : public FullFilterBlockBuilder { public: explicit PartitionedFilterBlockBuilder( const SliceTransform* prefix_extractor, bool whole_key_filtering, FilterBitsBuilder* filter_bits_builder, int index_block_restart_interval, PartitionedIndexBuilder* const p_index_builder, const uint32_t partition_size); virtual ~PartitionedFilterBlockBuilder(); void AddKey(const Slice& key) override; virtual Slice Finish(const BlockHandle& last_partition_block_handle, Status* status) override; private: // Filter data BlockBuilder index_on_filter_block_builder_; // top-level index builder struct FilterEntry { std::string key; Slice filter; }; std::list filters; // list of partitioned indexes and their keys std::unique_ptr value; std::vector> filter_gc; bool finishing_filters = false; // true if Finish is called once but not complete yet. // The policy of when cut a filter block and Finish it void MaybeCutAFilterBlock(); // Currently we keep the same number of partitions for filters and indexes. // This would allow for some potentioal optimizations in future. If such // optimizations did not realize we can use different number of partitions and // eliminate p_index_builder_ PartitionedIndexBuilder* const p_index_builder_; // The desired number of filters per partition uint32_t filters_per_partition_; // The current number of filters in the last partition uint32_t filters_in_partition_; }; class PartitionedFilterBlockReader : public FilterBlockReader { public: explicit PartitionedFilterBlockReader(const SliceTransform* prefix_extractor, bool whole_key_filtering, BlockContents&& contents, FilterBitsReader* filter_bits_reader, Statistics* stats, const Comparator& comparator, const BlockBasedTable* table); virtual ~PartitionedFilterBlockReader(); virtual bool IsBlockBased() override { return false; } virtual bool KeyMayMatch( const Slice& key, uint64_t block_offset = kNotValid, const bool no_io = false, const Slice* const const_ikey_ptr = nullptr) override; virtual bool PrefixMayMatch( const Slice& prefix, uint64_t block_offset = kNotValid, const bool no_io = false, const Slice* const const_ikey_ptr = nullptr) override; virtual size_t ApproximateMemoryUsage() const override; private: Slice GetFilterPartitionHandle(const Slice& entry); BlockBasedTable::CachableEntry GetFilterPartition( FilePrefetchBuffer* prefetch_buffer, Slice* handle, const bool no_io, bool* cached); virtual void CacheDependencies(bool pin) override; const SliceTransform* prefix_extractor_; std::unique_ptr idx_on_fltr_blk_; const Comparator& comparator_; const BlockBasedTable* table_; std::unordered_map> filter_map_; }; } // namespace rocksdb