diff --git a/HISTORY.md b/HISTORY.md index d041b3fe9..a300611b5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -21,6 +21,7 @@ * Remove deprecated Env::LoadEnv(). Use Env::CreateFromString() instead. * Remove deprecated FileSystem::Load(). Use FileSystem::CreateFromString() instead. * Removed the deprecated version of these utility functions and the corresponding Java bindings: `LoadOptionsFromFile`, `LoadLatestOptions`, `CheckOptionsCompatibility`. +* Remove the FactoryFunc from the LoadObject method from the Customizable helper methods. ### Public API Changes * Moved rarely-needed Cache class definition to new advanced_cache.h, and added a CacheWrapper class to advanced_cache.h. Minor changes to SimCache API definitions. diff --git a/cache/cache.cc b/cache/cache.cc index 8b02354f6..685368566 100644 --- a/cache/cache.cc +++ b/cache/cache.cc @@ -87,8 +87,7 @@ Status SecondaryCache::CreateFromString( } return status; } else { - return LoadSharedObject(config_options, value, nullptr, - result); + return LoadSharedObject(config_options, value, result); } } diff --git a/db/compaction/sst_partitioner.cc b/db/compaction/sst_partitioner.cc index 1067191d5..2f4d87935 100644 --- a/db/compaction/sst_partitioner.cc +++ b/db/compaction/sst_partitioner.cc @@ -78,7 +78,6 @@ Status SstPartitionerFactory::CreateFromString( std::call_once(once, [&]() { RegisterSstPartitionerFactories(*(ObjectLibrary::Default().get()), ""); }); - return LoadSharedObject(options, value, nullptr, - result); + return LoadSharedObject(options, value, result); } } // namespace ROCKSDB_NAMESPACE diff --git a/db/event_helpers.cc b/db/event_helpers.cc index 0a53f4a1a..4360144ec 100644 --- a/db/event_helpers.cc +++ b/db/event_helpers.cc @@ -13,7 +13,7 @@ namespace ROCKSDB_NAMESPACE { Status EventListener::CreateFromString(const ConfigOptions& config_options, const std::string& id, std::shared_ptr* result) { - return LoadSharedObject(config_options, id, nullptr, result); + return LoadSharedObject(config_options, id, result); } namespace { diff --git a/env/env.cc b/env/env.cc index f673ac57d..2137738c7 100644 --- a/env/env.cc +++ b/env/env.cc @@ -641,7 +641,7 @@ Status Env::CreateFromString(const ConfigOptions& config_options, } else { RegisterSystemEnvs(); Env* env = *result; - Status s = LoadStaticObject(config_options, value, nullptr, &env); + Status s = LoadStaticObject(config_options, value, &env); if (s.ok()) { *result = env; } @@ -1227,8 +1227,7 @@ Status SystemClock::CreateFromString(const ConfigOptions& config_options, std::call_once(once, [&]() { RegisterBuiltinSystemClocks(*(ObjectLibrary::Default().get()), ""); }); - return LoadSharedObject(config_options, value, nullptr, - result); + return LoadSharedObject(config_options, value, result); } } } // namespace ROCKSDB_NAMESPACE diff --git a/env/env_encryption.cc b/env/env_encryption.cc index 602c4be09..beb31a9cf 100644 --- a/env/env_encryption.cc +++ b/env/env_encryption.cc @@ -1332,15 +1332,14 @@ Status BlockCipher::CreateFromString(const ConfigOptions& config_options, const std::string& value, std::shared_ptr* result) { RegisterEncryptionBuiltins(); - return LoadSharedObject(config_options, value, nullptr, result); + return LoadSharedObject(config_options, value, result); } Status EncryptionProvider::CreateFromString( const ConfigOptions& config_options, const std::string& value, std::shared_ptr* result) { RegisterEncryptionBuiltins(); - return LoadSharedObject(config_options, value, nullptr, - result); + return LoadSharedObject(config_options, value, result); } diff --git a/env/file_system.cc b/env/file_system.cc index f166fd8a0..71fb4d5bc 100644 --- a/env/file_system.cc +++ b/env/file_system.cc @@ -91,7 +91,7 @@ Status FileSystem::CreateFromString(const ConfigOptions& config_options, std::call_once(once, [&]() { RegisterBuiltinFileSystems(*(ObjectLibrary::Default().get()), ""); }); - return LoadSharedObject(config_options, value, nullptr, result); + return LoadSharedObject(config_options, value, result); } } diff --git a/include/rocksdb/utilities/customizable_util.h b/include/rocksdb/utilities/customizable_util.h index b530eba6e..adf254054 100644 --- a/include/rocksdb/utilities/customizable_util.h +++ b/include/rocksdb/utilities/customizable_util.h @@ -13,7 +13,6 @@ // for more information on how to develop and use customizable objects #pragma once -#include #include #include @@ -24,24 +23,6 @@ #include "rocksdb/utilities/object_registry.h" namespace ROCKSDB_NAMESPACE { -// The FactoryFunc functions are used to create a new customizable object -// without going through the ObjectRegistry. This methodology is especially -// useful in LITE mode, where there is no ObjectRegistry. The methods take -// in an ID of the object to create and a pointer to store the created object. -// If the factory successfully recognized the input ID, the method should return -// success; otherwise false should be returned. On success, the object -// parameter contains the new object. -template -using SharedFactoryFunc = - std::function*)>; - -template -using UniqueFactoryFunc = - std::function*)>; - -template -using StaticFactoryFunc = std::function; - // Creates a new shared customizable instance object based on the // input parameters using the object registry. // @@ -156,12 +137,10 @@ static Status NewManagedObject( // handled // @param value Either the simple name of the instance to create, or a set of // name-value pairs to create and initailize the object -// @param func Optional function to call to attempt to create an instance // @param result The newly created instance. template static Status LoadSharedObject(const ConfigOptions& config_options, const std::string& value, - const SharedFactoryFunc& func, std::shared_ptr* result) { std::string id; std::unordered_map opt_map; @@ -170,12 +149,8 @@ static Status LoadSharedObject(const ConfigOptions& config_options, value, &id, &opt_map); if (!status.ok()) { // GetOptionsMap failed return status; - } else if (func == nullptr || - !func(id, result)) { // No factory, or it failed - return NewSharedObject(config_options, id, opt_map, result); } else { - return Customizable::ConfigureNewObject(config_options, result->get(), - opt_map); + return NewSharedObject(config_options, id, opt_map, result); } } @@ -204,7 +179,6 @@ static Status LoadSharedObject(const ConfigOptions& config_options, // handled // @param value Either the simple name of the instance to create, or a set of // name-value pairs to create and initailize the object -// @param func Optional function to call to attempt to create an instance // @param result The newly created instance. template static Status LoadManagedObject(const ConfigOptions& config_options, @@ -270,12 +244,10 @@ static Status NewUniqueObject( // handled // @param value Either the simple name of the instance to create, or a set of // name-value pairs to create and initailize the object -// @param func Optional function to call to attempt to create an instance // @param result The newly created instance. template static Status LoadUniqueObject(const ConfigOptions& config_options, const std::string& value, - const UniqueFactoryFunc& func, std::unique_ptr* result) { std::string id; std::unordered_map opt_map; @@ -283,12 +255,8 @@ static Status LoadUniqueObject(const ConfigOptions& config_options, value, &id, &opt_map); if (!status.ok()) { // GetOptionsMap failed return status; - } else if (func == nullptr || - !func(id, result)) { // No factory, or it failed - return NewUniqueObject(config_options, id, opt_map, result); } else { - return Customizable::ConfigureNewObject(config_options, result->get(), - opt_map); + return NewUniqueObject(config_options, id, opt_map, result); } } @@ -337,23 +305,18 @@ static Status NewStaticObject( // handled // @param value Either the simple name of the instance to create, or a set of // name-value pairs to create and initailize the object -// @param func Optional function to call to attempt to create an instance // @param result The newly created instance. template static Status LoadStaticObject(const ConfigOptions& config_options, - const std::string& value, - const StaticFactoryFunc& func, T** result) { + const std::string& value, T** result) { std::string id; std::unordered_map opt_map; Status status = Customizable::GetOptionsMap(config_options, *result, value, &id, &opt_map); if (!status.ok()) { // GetOptionsMap failed return status; - } else if (func == nullptr || - !func(id, result)) { // No factory, or it failed - return NewStaticObject(config_options, id, opt_map, result); } else { - return Customizable::ConfigureNewObject(config_options, *result, opt_map); + return NewStaticObject(config_options, id, opt_map, result); } } } // namespace ROCKSDB_NAMESPACE diff --git a/monitoring/statistics.cc b/monitoring/statistics.cc index 4864a07ac..f6dd61651 100644 --- a/monitoring/statistics.cc +++ b/monitoring/statistics.cc @@ -300,7 +300,7 @@ Status Statistics::CreateFromString(const ConfigOptions& config_options, } else if (id == kNullptrString) { result->reset(); } else { - s = LoadSharedObject(config_options, id, nullptr, result); + s = LoadSharedObject(config_options, id, result); } return s; } diff --git a/options/customizable_test.cc b/options/customizable_test.cc index 4de5bfaef..2f4f34ee9 100644 --- a/options/customizable_test.cc +++ b/options/customizable_test.cc @@ -160,19 +160,6 @@ class BCustomizable : public TestCustomizable { BOptions opts_; }; -static bool LoadSharedB(const std::string& id, - std::shared_ptr* result) { - if (id == "B") { - result->reset(new BCustomizable(id)); - return true; - } else if (id.empty()) { - result->reset(); - return true; - } else { - return false; - } -} - static int A_count = 0; static int RegisterCustomTestObjects(ObjectLibrary& library, const std::string& /*arg*/) { @@ -184,6 +171,12 @@ static int RegisterCustomTestObjects(ObjectLibrary& library, A_count++; return guard->get(); }); + library.AddFactory( + "B", [](const std::string& name, std::unique_ptr* guard, + std::string* /* msg */) { + guard->reset(new BCustomizable(name)); + return guard->get(); + }); library.AddFactory( "S", [](const std::string& name, @@ -252,46 +245,19 @@ static void GetMapFromProperties( Status TestCustomizable::CreateFromString( const ConfigOptions& config_options, const std::string& value, std::shared_ptr* result) { - return LoadSharedObject(config_options, value, LoadSharedB, - result); + return LoadSharedObject(config_options, value, result); } Status TestCustomizable::CreateFromString( const ConfigOptions& config_options, const std::string& value, std::unique_ptr* result) { - return LoadUniqueObject( - config_options, value, - [](const std::string& id, std::unique_ptr* u) { - if (id == "B") { - u->reset(new BCustomizable(id)); - return true; - } else if (id.empty()) { - u->reset(); - return true; - } else { - return false; - } - }, - result); + return LoadUniqueObject(config_options, value, result); } Status TestCustomizable::CreateFromString(const ConfigOptions& config_options, const std::string& value, TestCustomizable** result) { - return LoadStaticObject( - config_options, value, - [](const std::string& id, TestCustomizable** ptr) { - if (id == "B") { - *ptr = new BCustomizable(id); - return true; - } else if (id.empty()) { - *ptr = nullptr; - return true; - } else { - return false; - } - }, - result); + return LoadStaticObject(config_options, value, result); } class CustomizableTest : public testing::Test { @@ -980,70 +946,34 @@ TEST_F(CustomizableTest, IgnoreUnknownObjects) { std::unique_ptr unique; TestCustomizable* pointer = nullptr; ignore.ignore_unsupported_options = false; - ASSERT_NOK( - LoadSharedObject(ignore, "Unknown", nullptr, &shared)); - ASSERT_NOK( - LoadUniqueObject(ignore, "Unknown", nullptr, &unique)); - ASSERT_NOK( - LoadStaticObject(ignore, "Unknown", nullptr, &pointer)); + ASSERT_NOK(LoadSharedObject(ignore, "Unknown", &shared)); + ASSERT_NOK(LoadUniqueObject(ignore, "Unknown", &unique)); + ASSERT_NOK(LoadStaticObject(ignore, "Unknown", &pointer)); ASSERT_EQ(shared.get(), nullptr); ASSERT_EQ(unique.get(), nullptr); ASSERT_EQ(pointer, nullptr); ignore.ignore_unsupported_options = true; - ASSERT_OK( - LoadSharedObject(ignore, "Unknown", nullptr, &shared)); - ASSERT_OK( - LoadUniqueObject(ignore, "Unknown", nullptr, &unique)); - ASSERT_OK( - LoadStaticObject(ignore, "Unknown", nullptr, &pointer)); + ASSERT_OK(LoadSharedObject(ignore, "Unknown", &shared)); + ASSERT_OK(LoadUniqueObject(ignore, "Unknown", &unique)); + ASSERT_OK(LoadStaticObject(ignore, "Unknown", &pointer)); ASSERT_EQ(shared.get(), nullptr); ASSERT_EQ(unique.get(), nullptr); ASSERT_EQ(pointer, nullptr); - ASSERT_OK(LoadSharedObject(ignore, "id=Unknown", nullptr, - &shared)); - ASSERT_OK(LoadUniqueObject(ignore, "id=Unknown", nullptr, - &unique)); - ASSERT_OK(LoadStaticObject(ignore, "id=Unknown", nullptr, - &pointer)); + ASSERT_OK(LoadSharedObject(ignore, "id=Unknown", &shared)); + ASSERT_OK(LoadUniqueObject(ignore, "id=Unknown", &unique)); + ASSERT_OK(LoadStaticObject(ignore, "id=Unknown", &pointer)); ASSERT_EQ(shared.get(), nullptr); ASSERT_EQ(unique.get(), nullptr); ASSERT_EQ(pointer, nullptr); ASSERT_OK(LoadSharedObject(ignore, "id=Unknown;option=bad", - nullptr, &shared)); + &shared)); ASSERT_OK(LoadUniqueObject(ignore, "id=Unknown;option=bad", - nullptr, &unique)); + &unique)); ASSERT_OK(LoadStaticObject(ignore, "id=Unknown;option=bad", - nullptr, &pointer)); - ASSERT_EQ(shared.get(), nullptr); - ASSERT_EQ(unique.get(), nullptr); - ASSERT_EQ(pointer, nullptr); -} - -TEST_F(CustomizableTest, FactoryFunctionTest) { - std::shared_ptr shared; - std::unique_ptr unique; - TestCustomizable* pointer = nullptr; - ConfigOptions ignore = config_options_; - ignore.ignore_unsupported_options = false; - ASSERT_OK(TestCustomizable::CreateFromString(ignore, "B", &shared)); - ASSERT_OK(TestCustomizable::CreateFromString(ignore, "B", &unique)); - ASSERT_OK(TestCustomizable::CreateFromString(ignore, "B", &pointer)); - ASSERT_NE(shared.get(), nullptr); - ASSERT_NE(unique.get(), nullptr); - ASSERT_NE(pointer, nullptr); - delete pointer; - pointer = nullptr; - ASSERT_OK(TestCustomizable::CreateFromString(ignore, "id=", &shared)); - ASSERT_OK(TestCustomizable::CreateFromString(ignore, "id=", &unique)); - ASSERT_OK(TestCustomizable::CreateFromString(ignore, "id=", &pointer)); + &pointer)); ASSERT_EQ(shared.get(), nullptr); ASSERT_EQ(unique.get(), nullptr); ASSERT_EQ(pointer, nullptr); - ASSERT_NOK(TestCustomizable::CreateFromString(ignore, "option=bad", &shared)); - ASSERT_NOK(TestCustomizable::CreateFromString(ignore, "option=bad", &unique)); - ASSERT_NOK( - TestCustomizable::CreateFromString(ignore, "option=bad", &pointer)); - ASSERT_EQ(pointer, nullptr); } TEST_F(CustomizableTest, URLFactoryTest) { diff --git a/table/block_based/flush_block_policy.cc b/table/block_based/flush_block_policy.cc index 76fe85b1a..baac21e21 100644 --- a/table/block_based/flush_block_policy.cc +++ b/table/block_based/flush_block_policy.cc @@ -110,16 +110,6 @@ static int RegisterFlushBlockPolicyFactories(ObjectLibrary& library, return 2; } -static bool LoadFlushPolicyFactory( - const std::string& id, std::shared_ptr* result) { - if (id.empty()) { - result->reset(new FlushBlockBySizePolicyFactory()); - } else { - return false; - } - return true; -} - FlushBlockBySizePolicyFactory::FlushBlockBySizePolicyFactory() : FlushBlockPolicyFactory() {} @@ -130,7 +120,13 @@ Status FlushBlockPolicyFactory::CreateFromString( std::call_once(once, [&]() { RegisterFlushBlockPolicyFactories(*(ObjectLibrary::Default().get()), ""); }); - return LoadSharedObject( - config_options, value, LoadFlushPolicyFactory, factory); + + if (value.empty()) { + factory->reset(new FlushBlockBySizePolicyFactory()); + return Status::OK(); + } else { + return LoadSharedObject(config_options, value, + factory); + } } } // namespace ROCKSDB_NAMESPACE diff --git a/table/table_factory.cc b/table/table_factory.cc index ef44fe382..29b6c89f8 100644 --- a/table/table_factory.cc +++ b/table/table_factory.cc @@ -43,21 +43,10 @@ static void RegisterTableFactories(const std::string& /*arg*/) { }); } -static bool LoadFactory(const std::string& name, - std::shared_ptr* factory) { - if (name == TableFactory::kBlockBasedTableName()) { - factory->reset(new BlockBasedTableFactory()); - return true; - } else { - return false; - } -} - Status TableFactory::CreateFromString(const ConfigOptions& config_options, const std::string& value, std::shared_ptr* factory) { RegisterTableFactories(""); - return LoadSharedObject(config_options, value, LoadFactory, - factory); + return LoadSharedObject(config_options, value, factory); } } // namespace ROCKSDB_NAMESPACE diff --git a/util/file_checksum_helper.cc b/util/file_checksum_helper.cc index b35d3abb9..0c072e1e3 100644 --- a/util/file_checksum_helper.cc +++ b/util/file_checksum_helper.cc @@ -160,8 +160,7 @@ Status FileChecksumGenFactory::CreateFromString( *result = GetFileChecksumGenCrc32cFactory(); return Status::OK(); } else { - Status s = LoadSharedObject(options, value, nullptr, - result); + Status s = LoadSharedObject(options, value, result); return s; } } diff --git a/utilities/compaction_filters.cc b/utilities/compaction_filters.cc index cb14c48d9..999f72365 100644 --- a/utilities/compaction_filters.cc +++ b/utilities/compaction_filters.cc @@ -32,8 +32,8 @@ Status CompactionFilter::CreateFromString(const ConfigOptions& config_options, RegisterBuiltinCompactionFilters(*(ObjectLibrary::Default().get()), ""); }); CompactionFilter* filter = const_cast(*result); - Status status = LoadStaticObject(config_options, value, - nullptr, &filter); + Status status = + LoadStaticObject(config_options, value, &filter); if (status.ok()) { *result = const_cast(filter); } @@ -45,8 +45,8 @@ Status CompactionFilterFactory::CreateFromString( std::shared_ptr* result) { // Currently there are no builtin CompactionFilterFactories. // If any are introduced, they need to be registered here. - Status status = LoadSharedObject( - config_options, value, nullptr, result); + Status status = + LoadSharedObject(config_options, value, result); return status; } } // namespace ROCKSDB_NAMESPACE diff --git a/utilities/merge_operators.cc b/utilities/merge_operators.cc index 16e361ed4..020064d09 100644 --- a/utilities/merge_operators.cc +++ b/utilities/merge_operators.cc @@ -12,30 +12,14 @@ #include "rocksdb/utilities/customizable_util.h" #include "rocksdb/utilities/object_registry.h" #include "utilities/merge_operators/bytesxor.h" +#include "utilities/merge_operators/max_operator.h" +#include "utilities/merge_operators/put_operator.h" #include "utilities/merge_operators/sortlist.h" #include "utilities/merge_operators/string_append/stringappend.h" #include "utilities/merge_operators/string_append/stringappend2.h" +#include "utilities/merge_operators/uint64add.h" namespace ROCKSDB_NAMESPACE { -static bool LoadMergeOperator(const std::string& id, - std::shared_ptr* result) { - bool success = true; - // TODO: Hook the "name" up to the actual Name() of the MergeOperators? - // Requires these classes be moved into a header file... - if (id == "put" || id == "PutOperator") { - *result = MergeOperators::CreatePutOperator(); - } else if (id == "put_v1") { - *result = MergeOperators::CreateDeprecatedPutOperator(); - } else if (id == "uint64add" || id == "UInt64AddOperator") { - *result = MergeOperators::CreateUInt64AddOperator(); - } else if (id == "max" || id == "MaxOperator") { - *result = MergeOperators::CreateMaxOperator(); - } else { - success = false; - } - return success; -} - static int RegisterBuiltinMergeOperators(ObjectLibrary& library, const std::string& /*arg*/) { size_t num_types; @@ -71,6 +55,37 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library, guard->reset(new BytesXOROperator()); return guard->get(); }); + library.AddFactory( + ObjectLibrary::PatternEntry(UInt64AddOperator::kClassName()) + .AnotherName(UInt64AddOperator::kNickName()), + [](const std::string& /*uri*/, std::unique_ptr* guard, + std::string* /*errmsg*/) { + guard->reset(new UInt64AddOperator()); + return guard->get(); + }); + library.AddFactory( + ObjectLibrary::PatternEntry(MaxOperator::kClassName()) + .AnotherName(MaxOperator::kNickName()), + [](const std::string& /*uri*/, std::unique_ptr* guard, + std::string* /*errmsg*/) { + guard->reset(new MaxOperator()); + return guard->get(); + }); + library.AddFactory( + ObjectLibrary::PatternEntry(PutOperatorV2::kClassName()) + .AnotherName(PutOperatorV2::kNickName()), + [](const std::string& /*uri*/, std::unique_ptr* guard, + std::string* /*errmsg*/) { + guard->reset(new PutOperatorV2()); + return guard->get(); + }); + library.AddFactory( + ObjectLibrary::PatternEntry(PutOperator::kNickName()), + [](const std::string& /*uri*/, std::unique_ptr* guard, + std::string* /*errmsg*/) { + guard->reset(new PutOperator()); + return guard->get(); + }); return static_cast(library.GetFactoryCount(&num_types)); } @@ -82,8 +97,7 @@ Status MergeOperator::CreateFromString(const ConfigOptions& config_options, std::call_once(once, [&]() { RegisterBuiltinMergeOperators(*(ObjectLibrary::Default().get()), ""); }); - return LoadSharedObject(config_options, value, - LoadMergeOperator, result); + return LoadSharedObject(config_options, value, result); } std::shared_ptr MergeOperators::CreateFromStringId( diff --git a/utilities/merge_operators/max.cc b/utilities/merge_operators/max.cc index de4abfa6f..ff854cca3 100644 --- a/utilities/merge_operators/max.cc +++ b/utilities/merge_operators/max.cc @@ -8,71 +8,55 @@ #include "rocksdb/merge_operator.h" #include "rocksdb/slice.h" #include "utilities/merge_operators.h" +#include "utilities/merge_operators/max_operator.h" -using ROCKSDB_NAMESPACE::Logger; -using ROCKSDB_NAMESPACE::MergeOperator; -using ROCKSDB_NAMESPACE::Slice; - -namespace { // anonymous namespace - -// Merge operator that picks the maximum operand, Comparison is based on -// Slice::compare -class MaxOperator : public MergeOperator { - public: - bool FullMergeV2(const MergeOperationInput& merge_in, - MergeOperationOutput* merge_out) const override { - Slice& max = merge_out->existing_operand; - if (merge_in.existing_value) { - max = Slice(merge_in.existing_value->data(), - merge_in.existing_value->size()); - } else if (max.data() == nullptr) { - max = Slice(); - } - - for (const auto& op : merge_in.operand_list) { - if (max.compare(op) < 0) { - max = op; - } - } +namespace ROCKSDB_NAMESPACE { - return true; +bool MaxOperator::FullMergeV2(const MergeOperationInput& merge_in, + MergeOperationOutput* merge_out) const { + Slice& max = merge_out->existing_operand; + if (merge_in.existing_value) { + max = + Slice(merge_in.existing_value->data(), merge_in.existing_value->size()); + } else if (max.data() == nullptr) { + max = Slice(); } - bool PartialMerge(const Slice& /*key*/, const Slice& left_operand, - const Slice& right_operand, std::string* new_value, - Logger* /*logger*/) const override { - if (left_operand.compare(right_operand) >= 0) { - new_value->assign(left_operand.data(), left_operand.size()); - } else { - new_value->assign(right_operand.data(), right_operand.size()); + for (const auto& op : merge_in.operand_list) { + if (max.compare(op) < 0) { + max = op; } - return true; } - bool PartialMergeMulti(const Slice& /*key*/, - const std::deque& operand_list, - std::string* new_value, - Logger* /*logger*/) const override { - Slice max; - for (const auto& operand : operand_list) { - if (max.compare(operand) < 0) { - max = operand; - } - } + return true; +} - new_value->assign(max.data(), max.size()); - return true; +bool MaxOperator::PartialMerge(const Slice& /*key*/, const Slice& left_operand, + const Slice& right_operand, + std::string* new_value, + Logger* /*logger*/) const { + if (left_operand.compare(right_operand) >= 0) { + new_value->assign(left_operand.data(), left_operand.size()); + } else { + new_value->assign(right_operand.data(), right_operand.size()); } + return true; +} - static const char* kClassName() { return "MaxOperator"; } - static const char* kNickName() { return "max"; } - const char* Name() const override { return kClassName(); } - const char* NickName() const override { return kNickName(); } -}; - -} // end of anonymous namespace +bool MaxOperator::PartialMergeMulti(const Slice& /*key*/, + const std::deque& operand_list, + std::string* new_value, + Logger* /*logger*/) const { + Slice max; + for (const auto& operand : operand_list) { + if (max.compare(operand) < 0) { + max = operand; + } + } -namespace ROCKSDB_NAMESPACE { + new_value->assign(max.data(), max.size()); + return true; +} std::shared_ptr MergeOperators::CreateMaxOperator() { return std::make_shared(); diff --git a/utilities/merge_operators/max_operator.h b/utilities/merge_operators/max_operator.h new file mode 100644 index 000000000..4c8e98db4 --- /dev/null +++ b/utilities/merge_operators/max_operator.h @@ -0,0 +1,35 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under both the GPLv2 (found in the +// COPYING file in the root directory) and Apache 2.0 License +// (found in the LICENSE.Apache file in the root directory). +// +// Merge operator that picks the maximum operand, Comparison is based on +// Slice::compare + +#pragma once + +#include "rocksdb/merge_operator.h" + +namespace ROCKSDB_NAMESPACE { +class Logger; +class Slice; + +class MaxOperator : public MergeOperator { + public: + static const char* kClassName() { return "MaxOperator"; } + static const char* kNickName() { return "max"; } + const char* Name() const override { return kClassName(); } + const char* NickName() const override { return kNickName(); } + + bool FullMergeV2(const MergeOperationInput& merge_in, + MergeOperationOutput* merge_out) const override; + bool PartialMerge(const Slice& /*key*/, const Slice& left_operand, + const Slice& right_operand, std::string* new_value, + Logger* /*logger*/) const override; + bool PartialMergeMulti(const Slice& /*key*/, + const std::deque& operand_list, + std::string* new_value, + Logger* /*logger*/) const override; +}; + +} // namespace ROCKSDB_NAMESPACE diff --git a/utilities/merge_operators/put.cc b/utilities/merge_operators/put.cc index ccf9ff21f..79468c6b7 100644 --- a/utilities/merge_operators/put.cc +++ b/utilities/merge_operators/put.cc @@ -8,12 +8,9 @@ #include "rocksdb/merge_operator.h" #include "rocksdb/slice.h" #include "utilities/merge_operators.h" +#include "utilities/merge_operators/put_operator.h" -namespace { // anonymous namespace - -using ROCKSDB_NAMESPACE::Logger; -using ROCKSDB_NAMESPACE::MergeOperator; -using ROCKSDB_NAMESPACE::Slice; +namespace ROCKSDB_NAMESPACE { // A merge operator that mimics Put semantics // Since this merge-operator will not be used in production, @@ -23,64 +20,49 @@ using ROCKSDB_NAMESPACE::Slice; // which would be simpler in this case). // // From the client-perspective, semantics are the same. -class PutOperator : public MergeOperator { - public: - bool FullMerge(const Slice& /*key*/, const Slice* /*existing_value*/, - const std::deque& operand_sequence, - std::string* new_value, Logger* /*logger*/) const override { - // Put basically only looks at the current/latest value - assert(!operand_sequence.empty()); - assert(new_value != nullptr); - new_value->assign(operand_sequence.back()); - return true; - } - - bool PartialMerge(const Slice& /*key*/, const Slice& /*left_operand*/, - const Slice& right_operand, std::string* new_value, - Logger* /*logger*/) const override { - new_value->assign(right_operand.data(), right_operand.size()); - return true; - } - - using MergeOperator::PartialMergeMulti; - bool PartialMergeMulti(const Slice& /*key*/, - const std::deque& operand_list, - std::string* new_value, - Logger* /*logger*/) const override { - new_value->assign(operand_list.back().data(), operand_list.back().size()); - return true; - } - - static const char* kClassName() { return "PutOperator"; } - static const char* kNickName() { return "put_v1"; } - const char* Name() const override { return kClassName(); } - const char* NickName() const override { return kNickName(); } -}; - -class PutOperatorV2 : public PutOperator { - bool FullMerge(const Slice& /*key*/, const Slice* /*existing_value*/, - const std::deque& /*operand_sequence*/, - std::string* /*new_value*/, - Logger* /*logger*/) const override { - assert(false); - return false; - } +bool PutOperator::FullMerge(const Slice& /*key*/, + const Slice* /*existing_value*/, + const std::deque& operand_sequence, + std::string* new_value, Logger* /*logger*/) const { + // Put basically only looks at the current/latest value + assert(!operand_sequence.empty()); + assert(new_value != nullptr); + new_value->assign(operand_sequence.back()); + return true; +} - bool FullMergeV2(const MergeOperationInput& merge_in, - MergeOperationOutput* merge_out) const override { - // Put basically only looks at the current/latest value - assert(!merge_in.operand_list.empty()); - merge_out->existing_operand = merge_in.operand_list.back(); - return true; - } +bool PutOperator::PartialMerge(const Slice& /*key*/, + const Slice& /*left_operand*/, + const Slice& right_operand, + std::string* new_value, + Logger* /*logger*/) const { + new_value->assign(right_operand.data(), right_operand.size()); + return true; +} - static const char* kNickName() { return "put"; } - const char* NickName() const override { return kNickName(); } -}; +bool PutOperator::PartialMergeMulti(const Slice& /*key*/, + const std::deque& operand_list, + std::string* new_value, + Logger* /*logger*/) const { + new_value->assign(operand_list.back().data(), operand_list.back().size()); + return true; +} -} // end of anonymous namespace +bool PutOperatorV2::FullMerge( + const Slice& /*key*/, const Slice* /*existing_value*/, + const std::deque& /*operand_sequence*/, + std::string* /*new_value*/, Logger* /*logger*/) const { + assert(false); + return false; +} -namespace ROCKSDB_NAMESPACE { +bool PutOperatorV2::FullMergeV2(const MergeOperationInput& merge_in, + MergeOperationOutput* merge_out) const { + // Put basically only looks at the current/latest value + assert(!merge_in.operand_list.empty()); + merge_out->existing_operand = merge_in.operand_list.back(); + return true; +} std::shared_ptr MergeOperators::CreateDeprecatedPutOperator() { return std::make_shared(); diff --git a/utilities/merge_operators/put_operator.h b/utilities/merge_operators/put_operator.h new file mode 100644 index 000000000..7529da78e --- /dev/null +++ b/utilities/merge_operators/put_operator.h @@ -0,0 +1,56 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under both the GPLv2 (found in the +// COPYING file in the root directory) and Apache 2.0 License +// (found in the LICENSE.Apache file in the root directory). +// +// A merge operator that mimics Put semantics +// Since this merge-operator will not be used in production, +// it is implemented as a non-associative merge operator to illustrate the +// new interface and for testing purposes. (That is, we inherit from +// the MergeOperator class rather than the AssociativeMergeOperator +// which would be simpler in this case). +// +// From the client-perspective, semantics are the same. + +#pragma once + +#include "rocksdb/merge_operator.h" + +namespace ROCKSDB_NAMESPACE { +class Logger; +class Slice; + +class PutOperator : public MergeOperator { + public: + static const char* kClassName() { return "PutOperator"; } + static const char* kNickName() { return "put_v1"; } + const char* Name() const override { return kClassName(); } + const char* NickName() const override { return kNickName(); } + + bool FullMerge(const Slice& /*key*/, const Slice* /*existing_value*/, + const std::deque& operand_sequence, + std::string* new_value, Logger* /*logger*/) const override; + bool PartialMerge(const Slice& /*key*/, const Slice& left_operand, + const Slice& right_operand, std::string* new_value, + Logger* /*logger*/) const override; + using MergeOperator::PartialMergeMulti; + bool PartialMergeMulti(const Slice& /*key*/, + const std::deque& operand_list, + std::string* new_value, + Logger* /*logger*/) const override; +}; + +class PutOperatorV2 : public PutOperator { + public: + static const char* kNickName() { return "put"; } + const char* NickName() const override { return kNickName(); } + + bool FullMerge(const Slice& /*key*/, const Slice* /*existing_value*/, + const std::deque& /*operand_sequence*/, + std::string* /*new_value*/, Logger* /*logger*/) const override; + + bool FullMergeV2(const MergeOperationInput& merge_in, + MergeOperationOutput* merge_out) const override; +}; + +} // namespace ROCKSDB_NAMESPACE diff --git a/utilities/merge_operators/uint64add.cc b/utilities/merge_operators/uint64add.cc index 5be2f5641..72957761b 100644 --- a/utilities/merge_operators/uint64add.cc +++ b/utilities/merge_operators/uint64add.cc @@ -3,6 +3,8 @@ // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). +#include "utilities/merge_operators/uint64add.h" + #include #include "logging/logging.h" @@ -12,61 +14,40 @@ #include "util/coding.h" #include "utilities/merge_operators.h" -namespace { // anonymous namespace - -using ROCKSDB_NAMESPACE::AssociativeMergeOperator; -using ROCKSDB_NAMESPACE::InfoLogLevel; -using ROCKSDB_NAMESPACE::Logger; -using ROCKSDB_NAMESPACE::Slice; - -// A 'model' merge operator with uint64 addition semantics -// Implemented as an AssociativeMergeOperator for simplicity and example. -class UInt64AddOperator : public AssociativeMergeOperator { - public: - bool Merge(const Slice& /*key*/, const Slice* existing_value, - const Slice& value, std::string* new_value, - Logger* logger) const override { - uint64_t orig_value = 0; - if (existing_value) { - orig_value = DecodeInteger(*existing_value, logger); - } - uint64_t operand = DecodeInteger(value, logger); - - assert(new_value); - new_value->clear(); - ROCKSDB_NAMESPACE::PutFixed64(new_value, orig_value + operand); +namespace ROCKSDB_NAMESPACE { // anonymous namespace - return true; // Return true always since corruption will be treated as 0 +bool UInt64AddOperator::Merge(const Slice& /*key*/, const Slice* existing_value, + const Slice& value, std::string* new_value, + Logger* logger) const { + uint64_t orig_value = 0; + if (existing_value) { + orig_value = DecodeInteger(*existing_value, logger); } + uint64_t operand = DecodeInteger(value, logger); - static const char* kClassName() { return "UInt64AddOperator"; } - static const char* kNickName() { return "uint64add"; } - const char* Name() const override { return kClassName(); } - const char* NickName() const override { return kNickName(); } + assert(new_value); + new_value->clear(); + PutFixed64(new_value, orig_value + operand); - private: - // Takes the string and decodes it into a uint64_t - // On error, prints a message and returns 0 - uint64_t DecodeInteger(const Slice& value, Logger* logger) const { - uint64_t result = 0; - - if (value.size() == sizeof(uint64_t)) { - result = ROCKSDB_NAMESPACE::DecodeFixed64(value.data()); - } else if (logger != nullptr) { - // If value is corrupted, treat it as 0 - ROCKS_LOG_ERROR(logger, - "uint64 value corruption, size: %" ROCKSDB_PRIszt - " > %" ROCKSDB_PRIszt, - value.size(), sizeof(uint64_t)); - } + return true; // Return true always since corruption will be treated as 0 +} - return result; +uint64_t UInt64AddOperator::DecodeInteger(const Slice& value, + Logger* logger) const { + uint64_t result = 0; + + if (value.size() == sizeof(uint64_t)) { + result = DecodeFixed64(value.data()); + } else if (logger != nullptr) { + // If value is corrupted, treat it as 0 + ROCKS_LOG_ERROR(logger, + "uint64 value corruption, size: %" ROCKSDB_PRIszt + " > %" ROCKSDB_PRIszt, + value.size(), sizeof(uint64_t)); } -}; -} // anonymous namespace - -namespace ROCKSDB_NAMESPACE { + return result; +} std::shared_ptr MergeOperators::CreateUInt64AddOperator() { return std::make_shared(); diff --git a/utilities/merge_operators/uint64add.h b/utilities/merge_operators/uint64add.h new file mode 100644 index 000000000..7e232677a --- /dev/null +++ b/utilities/merge_operators/uint64add.h @@ -0,0 +1,35 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under both the GPLv2 (found in the +// COPYING file in the root directory) and Apache 2.0 License +// (found in the LICENSE.Apache file in the root directory). +// +// A 'model' merge operator with uint64 addition semantics +// Implemented as an AssociativeMergeOperator for simplicity and example. + +#pragma once + +#include "rocksdb/merge_operator.h" +#include "utilities/merge_operators.h" + +namespace ROCKSDB_NAMESPACE { +class Logger; +class Slice; + +class UInt64AddOperator : public AssociativeMergeOperator { + public: + static const char* kClassName() { return "UInt64AddOperator"; } + static const char* kNickName() { return "uint64add"; } + const char* Name() const override { return kClassName(); } + const char* NickName() const override { return kNickName(); } + + bool Merge(const Slice& /*key*/, const Slice* existing_value, + const Slice& value, std::string* new_value, + Logger* logger) const override; + + private: + // Takes the string and decodes it into a uint64_t + // On error, prints a message and returns 0 + uint64_t DecodeInteger(const Slice& value, Logger* logger) const; +}; + +} // namespace ROCKSDB_NAMESPACE diff --git a/utilities/table_properties_collectors/compact_on_deletion_collector.cc b/utilities/table_properties_collectors/compact_on_deletion_collector.cc index 95dea67ed..a3b5189da 100644 --- a/utilities/table_properties_collectors/compact_on_deletion_collector.cc +++ b/utilities/table_properties_collectors/compact_on_deletion_collector.cc @@ -215,7 +215,7 @@ Status TablePropertiesCollectorFactory::CreateFromString( ""); }); return LoadSharedObject(options, value, - nullptr, result); + result); } } // namespace ROCKSDB_NAMESPACE diff --git a/utilities/wal_filter.cc b/utilities/wal_filter.cc index 98bba3610..9fa36bf27 100644 --- a/utilities/wal_filter.cc +++ b/utilities/wal_filter.cc @@ -15,8 +15,7 @@ namespace ROCKSDB_NAMESPACE { Status WalFilter::CreateFromString(const ConfigOptions& config_options, const std::string& value, WalFilter** filter) { - Status s = - LoadStaticObject(config_options, value, nullptr, filter); + Status s = LoadStaticObject(config_options, value, filter); return s; }