Summary: This change will allow other table to reuse the code for meta blocks. Test Plan: all existing unit tests passed Reviewers: dhruba, haobo, sdong CC: leveldb Differential Revision: https://reviews.facebook.net/D14475main
parent
e1d92dfd2e
commit
90729f8b23
@ -0,0 +1,134 @@ |
||||
// 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 "table/meta_blocks.h" |
||||
|
||||
#include <map> |
||||
|
||||
#include "rocksdb/table_properties.h" |
||||
#include "table/format.h" |
||||
#include "util/coding.h" |
||||
|
||||
namespace rocksdb { |
||||
|
||||
MetaIndexBuilder::MetaIndexBuilder() |
||||
: meta_index_block_( |
||||
new BlockBuilder(1 /* restart interval */, BytewiseComparator())) { |
||||
} |
||||
|
||||
void MetaIndexBuilder::Add(const std::string& key, |
||||
const BlockHandle& handle) { |
||||
std::string handle_encoding; |
||||
handle.EncodeTo(&handle_encoding); |
||||
meta_block_handles_.insert({key, handle_encoding}); |
||||
} |
||||
|
||||
Slice MetaIndexBuilder::Finish() { |
||||
for (const auto& metablock : meta_block_handles_) { |
||||
meta_index_block_->Add(metablock.first, metablock.second); |
||||
} |
||||
return meta_index_block_->Finish(); |
||||
} |
||||
|
||||
PropertyBlockBuilder::PropertyBlockBuilder() |
||||
: properties_block_( |
||||
new BlockBuilder(1 /* restart interval */, BytewiseComparator())) { |
||||
} |
||||
|
||||
void PropertyBlockBuilder::Add(const std::string& name, |
||||
const std::string& val) { |
||||
props_.insert({name, val}); |
||||
} |
||||
|
||||
void PropertyBlockBuilder::Add(const std::string& name, uint64_t val) { |
||||
assert(props_.find(name) == props_.end()); |
||||
|
||||
std::string dst; |
||||
PutVarint64(&dst, val); |
||||
|
||||
Add(name, dst); |
||||
} |
||||
|
||||
void PropertyBlockBuilder::Add( |
||||
const UserCollectedProperties& user_collected_properties) { |
||||
for (const auto& prop : user_collected_properties) { |
||||
Add(prop.first, prop.second); |
||||
} |
||||
} |
||||
|
||||
void PropertyBlockBuilder::AddTableProperty(const TableProperties& props) { |
||||
Add(TablePropertiesNames::kRawKeySize, props.raw_key_size); |
||||
Add(TablePropertiesNames::kRawValueSize, props.raw_value_size); |
||||
Add(TablePropertiesNames::kDataSize, props.data_size); |
||||
Add(TablePropertiesNames::kIndexSize, props.index_size); |
||||
Add(TablePropertiesNames::kNumEntries, props.num_entries); |
||||
Add(TablePropertiesNames::kNumDataBlocks, props.num_data_blocks); |
||||
Add(TablePropertiesNames::kFilterSize, props.filter_size); |
||||
|
||||
if (!props.filter_policy_name.empty()) { |
||||
Add(TablePropertiesNames::kFilterPolicy, |
||||
props.filter_policy_name); |
||||
} |
||||
} |
||||
|
||||
Slice PropertyBlockBuilder::Finish() { |
||||
for (const auto& prop : props_) { |
||||
properties_block_->Add(prop.first, prop.second); |
||||
} |
||||
|
||||
return properties_block_->Finish(); |
||||
} |
||||
|
||||
void LogPropertiesCollectionError( |
||||
Logger* info_log, const std::string& method, const std::string& name) { |
||||
assert(method == "Add" || method == "Finish"); |
||||
|
||||
std::string msg = |
||||
"[Warning] encountered error when calling TablePropertiesCollector::" + |
||||
method + "() with collector name: " + name; |
||||
Log(info_log, "%s", msg.c_str()); |
||||
} |
||||
|
||||
bool NotifyCollectTableCollectorsOnAdd( |
||||
const Slice& key, |
||||
const Slice& value, |
||||
const Options::TablePropertiesCollectors& collectors, |
||||
Logger* info_log) { |
||||
bool all_succeeded = true; |
||||
for (auto collector : collectors) { |
||||
Status s = collector->Add(key, value); |
||||
all_succeeded = all_succeeded && s.ok(); |
||||
if (!s.ok()) { |
||||
LogPropertiesCollectionError( |
||||
info_log, "Add", /* method */ collector->Name() |
||||
); |
||||
} |
||||
} |
||||
return all_succeeded; |
||||
} |
||||
|
||||
bool NotifyCollectTableCollectorsOnFinish( |
||||
const Options::TablePropertiesCollectors& collectors, |
||||
Logger* info_log, |
||||
PropertyBlockBuilder* builder) { |
||||
bool all_succeeded = true; |
||||
for (auto collector : collectors) { |
||||
UserCollectedProperties user_collected_properties; |
||||
Status s = collector->Finish(&user_collected_properties); |
||||
|
||||
all_succeeded = all_succeeded && s.ok(); |
||||
if (!s.ok()) { |
||||
LogPropertiesCollectionError( |
||||
info_log, "Finish", /* method */ collector->Name() |
||||
); |
||||
} else { |
||||
builder->Add(user_collected_properties); |
||||
} |
||||
} |
||||
|
||||
return all_succeeded; |
||||
} |
||||
|
||||
} // namespace rocksdb
|
@ -0,0 +1,106 @@ |
||||
// 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 <map> |
||||
#include <memory> |
||||
#include <string> |
||||
|
||||
#include "rocksdb/comparator.h" |
||||
#include "rocksdb/options.h" |
||||
#include "rocksdb/slice.h" |
||||
#include "table/block_builder.h" |
||||
|
||||
namespace rocksdb { |
||||
|
||||
class BlockHandle; |
||||
class BlockBuilder; |
||||
class Logger; |
||||
struct TableProperties; |
||||
|
||||
// An STL style comparator that does the bytewise comparator comparasion
|
||||
// internally.
|
||||
struct BytewiseLessThan { |
||||
bool operator()(const std::string& key1, const std::string& key2) const { |
||||
// smaller entries will be placed in front.
|
||||
return comparator->Compare(key1, key2) <= 0; |
||||
} |
||||
|
||||
const Comparator* comparator = BytewiseComparator(); |
||||
}; |
||||
|
||||
// When writing to a block that requires entries to be sorted by
|
||||
// `BytewiseComparator`, we can buffer the content to `BytewiseSortedMap`
|
||||
// before writng to store.
|
||||
typedef std::map<std::string, std::string, BytewiseLessThan> BytewiseSortedMap; |
||||
|
||||
class MetaIndexBuilder { |
||||
public: |
||||
MetaIndexBuilder(const MetaIndexBuilder&) = delete; |
||||
MetaIndexBuilder& operator=(const MetaIndexBuilder&) = delete; |
||||
|
||||
MetaIndexBuilder(); |
||||
void Add(const std::string& key, const BlockHandle& handle); |
||||
|
||||
// Write all the added key/value pairs to the block and return the contents
|
||||
// of the block.
|
||||
Slice Finish(); |
||||
|
||||
private: |
||||
// * Key: meta block name
|
||||
// * Value: block handle to that meta block
|
||||
struct Rep; |
||||
Rep* rep_; |
||||
|
||||
// store the sorted key/handle of the metablocks.
|
||||
BytewiseSortedMap meta_block_handles_; |
||||
std::unique_ptr<BlockBuilder> meta_index_block_; |
||||
}; |
||||
|
||||
class PropertyBlockBuilder { |
||||
public: |
||||
PropertyBlockBuilder(const PropertyBlockBuilder&) = delete; |
||||
PropertyBlockBuilder& operator=(const PropertyBlockBuilder&) = delete; |
||||
|
||||
PropertyBlockBuilder(); |
||||
|
||||
void AddTableProperty(const TableProperties& props); |
||||
void Add(const std::string& key, uint64_t value); |
||||
void Add(const std::string& key, const std::string& value); |
||||
void Add(const UserCollectedProperties& user_collected_properties); |
||||
|
||||
// Write all the added entries to the block and return the block contents
|
||||
Slice Finish(); |
||||
|
||||
private: |
||||
std::unique_ptr<BlockBuilder> properties_block_; |
||||
BytewiseSortedMap props_; |
||||
}; |
||||
|
||||
// Were we encounter any error occurs during user-defined statistics collection,
|
||||
// we'll write the warning message to info log.
|
||||
void LogPropertiesCollectionError( |
||||
Logger* info_log, const std::string& method, const std::string& name); |
||||
|
||||
// Utility functions help table builder to trigger batch events for user
|
||||
// defined property collectors.
|
||||
// Return value indicates if there is any error occurred; if error occurred,
|
||||
// the warning message will be logged.
|
||||
// NotifyCollectTableCollectorsOnAdd() triggers the `Add` event for all
|
||||
// property collectors.
|
||||
bool NotifyCollectTableCollectorsOnAdd( |
||||
const Slice& key, |
||||
const Slice& value, |
||||
const Options::TablePropertiesCollectors& collectors, |
||||
Logger* info_log); |
||||
|
||||
// NotifyCollectTableCollectorsOnAdd() triggers the `Finish` event for all
|
||||
// property collectors. The collected properties will be added to `builder`.
|
||||
bool NotifyCollectTableCollectorsOnFinish( |
||||
const Options::TablePropertiesCollectors& collectors, |
||||
Logger* info_log, |
||||
PropertyBlockBuilder* builder); |
||||
|
||||
} // namespace rocksdb
|
@ -0,0 +1,108 @@ |
||||
// 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/table_properties.h" |
||||
|
||||
namespace rocksdb { |
||||
|
||||
namespace { |
||||
void AppendProperty( |
||||
std::string& props, |
||||
const std::string& key, |
||||
const std::string& value, |
||||
const std::string& prop_delim, |
||||
const std::string& kv_delim) { |
||||
props.append(key); |
||||
props.append(kv_delim); |
||||
props.append(value); |
||||
props.append(prop_delim); |
||||
} |
||||
|
||||
template <class TValue> |
||||
void AppendProperty( |
||||
std::string& props, |
||||
const std::string& key, |
||||
const TValue& value, |
||||
const std::string& prop_delim, |
||||
const std::string& kv_delim) { |
||||
AppendProperty( |
||||
props, key, std::to_string(value), prop_delim, kv_delim |
||||
); |
||||
} |
||||
} |
||||
|
||||
std::string TableProperties::ToString( |
||||
const std::string& prop_delim, |
||||
const std::string& kv_delim) const { |
||||
std::string result; |
||||
result.reserve(1024); |
||||
|
||||
// Basic Info
|
||||
AppendProperty( |
||||
result, "# data blocks", num_data_blocks, prop_delim, kv_delim |
||||
); |
||||
AppendProperty(result, "# entries", num_entries, prop_delim, kv_delim); |
||||
|
||||
AppendProperty(result, "raw key size", raw_key_size, prop_delim, kv_delim); |
||||
AppendProperty( |
||||
result, |
||||
"raw average key size", |
||||
num_entries != 0 ? 1.0 * raw_key_size / num_entries : 0.0, |
||||
prop_delim, |
||||
kv_delim |
||||
); |
||||
AppendProperty( |
||||
result, "raw value size", raw_value_size, prop_delim, kv_delim |
||||
); |
||||
AppendProperty( |
||||
result, |
||||
"raw average value size", |
||||
num_entries != 0 ? 1.0 * raw_value_size / num_entries : 0.0, |
||||
prop_delim, |
||||
kv_delim |
||||
); |
||||
|
||||
AppendProperty(result, "data block size", data_size, prop_delim, kv_delim); |
||||
AppendProperty(result, "index block size", index_size, prop_delim, kv_delim); |
||||
AppendProperty( |
||||
result, "filter block size", filter_size, prop_delim, kv_delim |
||||
); |
||||
AppendProperty( |
||||
result, |
||||
"(estimated) table size", |
||||
data_size + index_size + filter_size, |
||||
prop_delim, |
||||
kv_delim |
||||
); |
||||
|
||||
AppendProperty( |
||||
result, |
||||
"filter policy name", |
||||
filter_policy_name.empty() ? std::string("N/A") : filter_policy_name, |
||||
prop_delim, |
||||
kv_delim |
||||
); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
const std::string TablePropertiesNames::kDataSize = |
||||
"rocksdb.data.size"; |
||||
const std::string TablePropertiesNames::kIndexSize = |
||||
"rocksdb.index.size"; |
||||
const std::string TablePropertiesNames::kFilterSize = |
||||
"rocksdb.filter.size"; |
||||
const std::string TablePropertiesNames::kRawKeySize = |
||||
"rocksdb.raw.key.size"; |
||||
const std::string TablePropertiesNames::kRawValueSize = |
||||
"rocksdb.raw.value.size"; |
||||
const std::string TablePropertiesNames::kNumDataBlocks = |
||||
"rocksdb.num.data.blocks"; |
||||
const std::string TablePropertiesNames::kNumEntries = |
||||
"rocksdb.num.entries"; |
||||
const std::string TablePropertiesNames::kFilterPolicy = |
||||
"rocksdb.filter.policy"; |
||||
|
||||
} // namespace rocksdb
|
Loading…
Reference in new issue