Summary: Allow block based table to configure the way flushing the blocks. This feature will allow us to add support for prefix-aligned block. Test Plan: make check Reviewers: dhruba, haobo, sdong, igor Reviewed By: sdong CC: leveldb Differential Revision: https://reviews.facebook.net/D13875main
parent
bba6595b1f
commit
fd075d6edd
@ -0,0 +1,64 @@ |
|||||||
|
// Copyright (c) 2013, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
class Slice; |
||||||
|
class BlockBuilder; |
||||||
|
|
||||||
|
// FlushBlockPolicy provides a configurable way to determine when to flush a
|
||||||
|
// block in the block based tables,
|
||||||
|
class FlushBlockPolicy { |
||||||
|
public: |
||||||
|
// Keep track of the key/value sequences and return the boolean value to
|
||||||
|
// determine if table builder should flush current data block.
|
||||||
|
virtual bool Update(const Slice& key, |
||||||
|
const Slice& value) = 0; |
||||||
|
|
||||||
|
virtual ~FlushBlockPolicy() { } |
||||||
|
}; |
||||||
|
|
||||||
|
class FlushBlockPolicyFactory { |
||||||
|
public: |
||||||
|
// Return the name of the flush block policy.
|
||||||
|
virtual const char* Name() const = 0; |
||||||
|
|
||||||
|
// Return a new block flush policy that flushes data blocks by data size.
|
||||||
|
// FlushBlockPolicy may need to access the metadata of the data block
|
||||||
|
// builder to determine when to flush the blocks.
|
||||||
|
//
|
||||||
|
// Callers must delete the result after any database that is using the
|
||||||
|
// result has been closed.
|
||||||
|
virtual FlushBlockPolicy* NewFlushBlockPolicy( |
||||||
|
const BlockBuilder& data_block_builder) const = 0; |
||||||
|
|
||||||
|
virtual ~FlushBlockPolicyFactory() { } |
||||||
|
}; |
||||||
|
|
||||||
|
class FlushBlockBySizePolicyFactory : public FlushBlockPolicyFactory { |
||||||
|
public: |
||||||
|
FlushBlockBySizePolicyFactory(const uint64_t block_size, |
||||||
|
const uint64_t block_size_deviation) : |
||||||
|
block_size_(block_size), |
||||||
|
block_size_deviation_(block_size_deviation) { |
||||||
|
} |
||||||
|
|
||||||
|
virtual const char* Name() const override { |
||||||
|
return "FlushBlockBySizePolicyFactory"; |
||||||
|
} |
||||||
|
|
||||||
|
virtual FlushBlockPolicy* NewFlushBlockPolicy( |
||||||
|
const BlockBuilder& data_block_builder) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const uint64_t block_size_; |
||||||
|
const uint64_t block_size_deviation_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // rocksdb
|
@ -0,0 +1,65 @@ |
|||||||
|
// Copyright (c) 2013, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#include "rocksdb/flush_block_policy.h" |
||||||
|
#include "rocksdb/slice.h" |
||||||
|
#include "table/block_builder.h" |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
// Flush block by size
|
||||||
|
class FlushBlockBySizePolicy : public FlushBlockPolicy { |
||||||
|
public: |
||||||
|
// @params block_size: Approximate size of user data packed per
|
||||||
|
// block.
|
||||||
|
// @params block_size_deviation: This is used to close a block before it
|
||||||
|
// reaches the configured
|
||||||
|
FlushBlockBySizePolicy(const uint64_t block_size, |
||||||
|
const uint64_t block_size_deviation, |
||||||
|
const BlockBuilder& data_block_builder) : |
||||||
|
block_size_(block_size), |
||||||
|
block_size_deviation_(block_size_deviation), |
||||||
|
data_block_builder_(data_block_builder) { |
||||||
|
} |
||||||
|
|
||||||
|
virtual bool Update(const Slice& key, |
||||||
|
const Slice& value) override { |
||||||
|
auto curr_size = data_block_builder_.CurrentSizeEstimate(); |
||||||
|
|
||||||
|
// Do flush if one of the below two conditions is true:
|
||||||
|
// 1) if the current estimated size already exceeds the block size,
|
||||||
|
// 2) block_size_deviation is set and the estimated size after appending
|
||||||
|
// the kv will exceed the block size and the current size is under the
|
||||||
|
// the deviation.
|
||||||
|
return curr_size >= block_size_ || BlockAlmostFull(key, value); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
bool BlockAlmostFull(const Slice& key, const Slice& value) const { |
||||||
|
const auto curr_size = data_block_builder_.CurrentSizeEstimate(); |
||||||
|
const auto estimated_size_after = |
||||||
|
data_block_builder_.EstimateSizeAfterKV(key, value); |
||||||
|
|
||||||
|
return |
||||||
|
estimated_size_after > block_size_ && |
||||||
|
block_size_deviation_ > 0 && |
||||||
|
curr_size * 100 > block_size_ * (100 - block_size_deviation_); |
||||||
|
} |
||||||
|
|
||||||
|
const uint64_t block_size_; |
||||||
|
const uint64_t block_size_deviation_; |
||||||
|
const BlockBuilder& data_block_builder_; |
||||||
|
}; |
||||||
|
|
||||||
|
FlushBlockPolicy* FlushBlockBySizePolicyFactory::NewFlushBlockPolicy( |
||||||
|
const BlockBuilder& data_block_builder) const { |
||||||
|
return new FlushBlockBySizePolicy(block_size_, |
||||||
|
block_size_deviation_, |
||||||
|
data_block_builder); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace rocksdb
|
Loading…
Reference in new issue