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