#include <algorithm>
#include <cinttypes>
#include <cstdio>
+
+#include "rocksdb/convenience.h"
#include "rocksdb/statistics.h"
+#include "rocksdb/utilities/customizable_util.h"
+#include "rocksdb/utilities/options_type.h"
+#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
return std::make_shared<StatisticsImpl>(nullptr);
}
+#ifndef ROCKSDB_LITE
+static int RegisterBuiltinStatistics(ObjectLibrary& library,
+ const std::string& /*arg*/) {
+ library.Register<Statistics>(
+ StatisticsImpl::kClassName(),
+ [](const std::string& /*uri*/, std::unique_ptr<Statistics>* guard,
+ std::string* /* errmsg */) {
+ guard->reset(new StatisticsImpl(nullptr));
+ return guard->get();
+ });
+ return 1;
+}
+#endif // ROCKSDB_LITE
+
+Status Statistics::CreateFromString(const ConfigOptions& config_options,
+ const std::string& id,
+ std::shared_ptr<Statistics>* result) {
+#ifndef ROCKSDB_LITE
+ static std::once_flag once;
+ std::call_once(once, [&]() {
+ RegisterBuiltinStatistics(*(ObjectLibrary::Default().get()), "");
+ });
+#endif // ROCKSDB_LITE
+ Status s;
+ if (id == "" || id == StatisticsImpl::kClassName()) {
+ result->reset(new StatisticsImpl(nullptr));
+ } else if (id == kNullptrString) {
+ result->reset();
+ } else {
+ s = LoadSharedObject<Statistics>(config_options, id, nullptr, result);
+ }
+ return s;
+}
+
+static std::unordered_map<std::string, OptionTypeInfo> stats_type_info = {
+#ifndef ROCKSDB_LITE
+ {"inner", OptionTypeInfo::AsCustomSharedPtr<Statistics>(
+ 0, OptionVerificationType::kByNameAllowFromNull,
+ OptionTypeFlags::kCompareNever)},
+#endif // !ROCKSDB_LITE
+};
+
StatisticsImpl::StatisticsImpl(std::shared_ptr<Statistics> stats)
- : stats_(std::move(stats)) {}
+ : stats_(std::move(stats)) {
+ RegisterOptions("StatisticsOptions", &stats_, &stats_type_info);
+}
StatisticsImpl::~StatisticsImpl() {}
#include "rocksdb/env_encryption.h"
#include "rocksdb/flush_block_policy.h"
#include "rocksdb/secondary_cache.h"
+#include "rocksdb/statistics.h"
#include "rocksdb/utilities/customizable_util.h"
#include "rocksdb/utilities/object_registry.h"
#include "rocksdb/utilities/options_type.h"
std::string GetPrintableOptions() const override { return ""; }
};
+class TestStatistics : public StatisticsImpl {
+ public:
+ TestStatistics() : StatisticsImpl(nullptr) {}
+ const char* Name() const override { return kClassName(); }
+ static const char* kClassName() { return "Test"; }
+};
+
+class TestFlushBlockPolicyFactory : public FlushBlockPolicyFactory {
+ public:
+ TestFlushBlockPolicyFactory() {}
+
+ static const char* kClassName() { return "TestFlushBlockPolicyFactory"; }
+ const char* Name() const override { return kClassName(); }
+
+ FlushBlockPolicy* NewFlushBlockPolicy(
+ const BlockBasedTableOptions& /*table_options*/,
+ const BlockBuilder& /*data_block_builder*/) const override {
+ return nullptr;
+ }
+};
+
#ifndef ROCKSDB_LITE
class MockEncryptionProvider : public EncryptionProvider {
public:
Status Encrypt(char* /*data*/) override { return Status::NotSupported(); }
Status Decrypt(char* data) override { return Encrypt(data); }
};
-#endif // ROCKSDB_LITE
-
-class TestFlushBlockPolicyFactory : public FlushBlockPolicyFactory {
- public:
- TestFlushBlockPolicyFactory() {}
-
- static const char* kClassName() { return "TestFlushBlockPolicyFactory"; }
- const char* Name() const override { return kClassName(); }
-
- FlushBlockPolicy* NewFlushBlockPolicy(
- const BlockBasedTableOptions& /*table_options*/,
- const BlockBuilder& /*data_block_builder*/) const override {
- return nullptr;
- }
-};
-#ifndef ROCKSDB_LITE
static int RegisterLocalObjects(ObjectLibrary& library,
const std::string& /*arg*/) {
size_t num_types;
return guard->get();
});
// Load any locally defined objects here
+ library.Register<Statistics>(
+ TestStatistics::kClassName(),
+ [](const std::string& /*uri*/, std::unique_ptr<Statistics>* guard,
+ std::string* /* errmsg */) {
+ guard->reset(new TestStatistics());
+ return guard->get();
+ });
+
library.Register<EncryptionProvider>(
"Mock(://test)?",
[](const std::string& uri, std::unique_ptr<EncryptionProvider>* guard,
}
}
+TEST_F(LoadCustomizableTest, LoadStatisticsTest) {
+ std::shared_ptr<Statistics> stats;
+ ASSERT_NOK(Statistics::CreateFromString(
+ config_options_, TestStatistics::kClassName(), &stats));
+ ASSERT_OK(
+ Statistics::CreateFromString(config_options_, "BasicStatistics", &stats));
+ ASSERT_NE(stats, nullptr);
+ ASSERT_EQ(stats->Name(), std::string("BasicStatistics"));
+#ifndef ROCKSDB_LITE
+ ASSERT_NOK(GetDBOptionsFromString(config_options_, db_opts_,
+ "statistics=Test", &db_opts_));
+ ASSERT_OK(GetDBOptionsFromString(config_options_, db_opts_,
+ "statistics=BasicStatistics", &db_opts_));
+ ASSERT_NE(db_opts_.statistics, nullptr);
+ ASSERT_STREQ(db_opts_.statistics->Name(), "BasicStatistics");
+
+ if (RegisterTests("test")) {
+ ASSERT_OK(Statistics::CreateFromString(
+ config_options_, TestStatistics::kClassName(), &stats));
+ ASSERT_NE(stats, nullptr);
+ ASSERT_STREQ(stats->Name(), TestStatistics::kClassName());
+
+ ASSERT_OK(GetDBOptionsFromString(config_options_, db_opts_,
+ "statistics=Test", &db_opts_));
+ ASSERT_NE(db_opts_.statistics, nullptr);
+ ASSERT_STREQ(db_opts_.statistics->Name(), TestStatistics::kClassName());
+
+ ASSERT_OK(GetDBOptionsFromString(
+ config_options_, db_opts_, "statistics={id=Test;inner=BasicStatistics}",
+ &db_opts_));
+ ASSERT_NE(db_opts_.statistics, nullptr);
+ ASSERT_STREQ(db_opts_.statistics->Name(), TestStatistics::kClassName());
+ auto* inner = db_opts_.statistics->GetOptions<std::shared_ptr<Statistics>>(
+ "StatisticsOptions");
+ ASSERT_NE(inner, nullptr);
+ ASSERT_NE(inner->get(), nullptr);
+ ASSERT_STREQ(inner->get()->Name(), "BasicStatistics");
+
+ ASSERT_OK(Statistics::CreateFromString(
+ config_options_, "id=BasicStatistics;inner=Test", &stats));
+ ASSERT_NE(stats, nullptr);
+ ASSERT_STREQ(stats->Name(), "BasicStatistics");
+ inner = stats->GetOptions<std::shared_ptr<Statistics>>("StatisticsOptions");
+ ASSERT_NE(inner, nullptr);
+ ASSERT_NE(inner->get(), nullptr);
+ ASSERT_STREQ(inner->get()->Name(), TestStatistics::kClassName());
+ }
+#endif
+}
+
TEST_F(LoadCustomizableTest, LoadMemTableRepFactoryTest) {
std::unique_ptr<MemTableRepFactory> result;
ASSERT_NOK(MemTableRepFactory::CreateFromString(
std::shared_ptr<TableFactory> table;
std::shared_ptr<FlushBlockPolicyFactory> result;
ASSERT_NOK(FlushBlockPolicyFactory::CreateFromString(
- config_options_, "TestFlushBlockPolicyFactory", &result));
+ config_options_, TestFlushBlockPolicyFactory::kClassName(), &result));
ASSERT_OK(
FlushBlockPolicyFactory::CreateFromString(config_options_, "", &result));
FlushBlockEveryKeyPolicyFactory::kClassName());
if (RegisterTests("Test")) {
ASSERT_OK(FlushBlockPolicyFactory::CreateFromString(
- config_options_, "TestFlushBlockPolicyFactory", &result));
+ config_options_, TestFlushBlockPolicyFactory::kClassName(), &result));
ASSERT_NE(result, nullptr);
- ASSERT_STREQ(result->Name(), "TestFlushBlockPolicyFactory");
+ ASSERT_STREQ(result->Name(), TestFlushBlockPolicyFactory::kClassName());
ASSERT_OK(TableFactory::CreateFromString(
- config_options_, table_opts + "TestFlushBlockPolicyFactory", &table));
+ config_options_, table_opts + TestFlushBlockPolicyFactory::kClassName(),
+ &table));
bbto = table->GetOptions<BlockBasedTableOptions>();
ASSERT_NE(bbto, nullptr);
ASSERT_NE(bbto->flush_block_policy_factory.get(), nullptr);
ASSERT_STREQ(bbto->flush_block_policy_factory->Name(),
- "TestFlushBlockPolicyFactory");
+ TestFlushBlockPolicyFactory::kClassName());
}
#endif // ROCKSDB_LITE
}