]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | // This source code is licensed under the BSD-style license found in the | |
3 | // LICENSE file in the root directory of this source tree. An additional grant | |
4 | // of patent rights can be found in the PATENTS file in the same directory. | |
5 | ||
6 | #include "rocksdb/options.h" | |
7 | #include "rocksdb/flush_block_policy.h" | |
8 | #include "rocksdb/slice.h" | |
9 | #include "table/block_builder.h" | |
10 | ||
11 | #include <cassert> | |
12 | ||
13 | namespace rocksdb { | |
14 | ||
15 | // Flush block by size | |
16 | class FlushBlockBySizePolicy : public FlushBlockPolicy { | |
17 | public: | |
18 | // @params block_size: Approximate size of user data packed per | |
19 | // block. | |
20 | // @params block_size_deviation: This is used to close a block before it | |
21 | // reaches the configured | |
22 | FlushBlockBySizePolicy(const uint64_t block_size, | |
23 | const uint64_t block_size_deviation, | |
24 | const BlockBuilder& data_block_builder) | |
25 | : block_size_(block_size), | |
26 | block_size_deviation_limit_( | |
27 | ((block_size * (100 - block_size_deviation)) + 99) / 100), | |
28 | data_block_builder_(data_block_builder) {} | |
29 | ||
30 | virtual bool Update(const Slice& key, | |
31 | const Slice& value) override { | |
32 | // it makes no sense to flush when the data block is empty | |
33 | if (data_block_builder_.empty()) { | |
34 | return false; | |
35 | } | |
36 | ||
37 | auto curr_size = data_block_builder_.CurrentSizeEstimate(); | |
38 | ||
39 | // Do flush if one of the below two conditions is true: | |
40 | // 1) if the current estimated size already exceeds the block size, | |
41 | // 2) block_size_deviation is set and the estimated size after appending | |
42 | // the kv will exceed the block size and the current size is under the | |
43 | // the deviation. | |
44 | return curr_size >= block_size_ || BlockAlmostFull(key, value); | |
45 | } | |
46 | ||
47 | private: | |
48 | bool BlockAlmostFull(const Slice& key, const Slice& value) const { | |
49 | if (block_size_deviation_limit_ == 0) { | |
50 | return false; | |
51 | } | |
52 | ||
53 | const auto curr_size = data_block_builder_.CurrentSizeEstimate(); | |
54 | const auto estimated_size_after = | |
55 | data_block_builder_.EstimateSizeAfterKV(key, value); | |
56 | ||
57 | return estimated_size_after > block_size_ && | |
58 | curr_size > block_size_deviation_limit_; | |
59 | } | |
60 | ||
61 | const uint64_t block_size_; | |
62 | const uint64_t block_size_deviation_limit_; | |
63 | const BlockBuilder& data_block_builder_; | |
64 | }; | |
65 | ||
66 | FlushBlockPolicy* FlushBlockBySizePolicyFactory::NewFlushBlockPolicy( | |
67 | const BlockBasedTableOptions& table_options, | |
68 | const BlockBuilder& data_block_builder) const { | |
69 | return new FlushBlockBySizePolicy( | |
70 | table_options.block_size, table_options.block_size_deviation, | |
71 | data_block_builder); | |
72 | } | |
73 | ||
74 | FlushBlockPolicy* FlushBlockBySizePolicyFactory::NewFlushBlockPolicy( | |
75 | const uint64_t size, const int deviation, | |
76 | const BlockBuilder& data_block_builder) { | |
77 | return new FlushBlockBySizePolicy(size, deviation, data_block_builder); | |
78 | } | |
79 | ||
80 | } // namespace rocksdb |