* 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.
}
return status;
} else {
- return LoadSharedObject<SecondaryCache>(config_options, value, nullptr,
- result);
+ return LoadSharedObject<SecondaryCache>(config_options, value, result);
}
}
std::call_once(once, [&]() {
RegisterSstPartitionerFactories(*(ObjectLibrary::Default().get()), "");
});
- return LoadSharedObject<SstPartitionerFactory>(options, value, nullptr,
- result);
+ return LoadSharedObject<SstPartitionerFactory>(options, value, result);
}
} // namespace ROCKSDB_NAMESPACE
Status EventListener::CreateFromString(const ConfigOptions& config_options,
const std::string& id,
std::shared_ptr<EventListener>* result) {
- return LoadSharedObject<EventListener>(config_options, id, nullptr, result);
+ return LoadSharedObject<EventListener>(config_options, id, result);
}
namespace {
} else {
RegisterSystemEnvs();
Env* env = *result;
- Status s = LoadStaticObject<Env>(config_options, value, nullptr, &env);
+ Status s = LoadStaticObject<Env>(config_options, value, &env);
if (s.ok()) {
*result = env;
}
std::call_once(once, [&]() {
RegisterBuiltinSystemClocks(*(ObjectLibrary::Default().get()), "");
});
- return LoadSharedObject<SystemClock>(config_options, value, nullptr,
- result);
+ return LoadSharedObject<SystemClock>(config_options, value, result);
}
}
} // namespace ROCKSDB_NAMESPACE
const std::string& value,
std::shared_ptr<BlockCipher>* result) {
RegisterEncryptionBuiltins();
- return LoadSharedObject<BlockCipher>(config_options, value, nullptr, result);
+ return LoadSharedObject<BlockCipher>(config_options, value, result);
}
Status EncryptionProvider::CreateFromString(
const ConfigOptions& config_options, const std::string& value,
std::shared_ptr<EncryptionProvider>* result) {
RegisterEncryptionBuiltins();
- return LoadSharedObject<EncryptionProvider>(config_options, value, nullptr,
- result);
+ return LoadSharedObject<EncryptionProvider>(config_options, value, result);
}
std::call_once(once, [&]() {
RegisterBuiltinFileSystems(*(ObjectLibrary::Default().get()), "");
});
- return LoadSharedObject<FileSystem>(config_options, value, nullptr, result);
+ return LoadSharedObject<FileSystem>(config_options, value, result);
}
}
// for more information on how to develop and use customizable objects
#pragma once
-#include <functional>
#include <memory>
#include <unordered_map>
#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 <typename T>
-using SharedFactoryFunc =
- std::function<bool(const std::string&, std::shared_ptr<T>*)>;
-
-template <typename T>
-using UniqueFactoryFunc =
- std::function<bool(const std::string&, std::unique_ptr<T>*)>;
-
-template <typename T>
-using StaticFactoryFunc = std::function<bool(const std::string&, T**)>;
-
// Creates a new shared customizable instance object based on the
// input parameters using the object registry.
//
// 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 <typename T>
static Status LoadSharedObject(const ConfigOptions& config_options,
const std::string& value,
- const SharedFactoryFunc<T>& func,
std::shared_ptr<T>* result) {
std::string id;
std::unordered_map<std::string, std::string> opt_map;
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);
}
}
// 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 <typename T>
static Status LoadManagedObject(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 <typename T>
static Status LoadUniqueObject(const ConfigOptions& config_options,
const std::string& value,
- const UniqueFactoryFunc<T>& func,
std::unique_ptr<T>* result) {
std::string id;
std::unordered_map<std::string, std::string> opt_map;
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);
}
}
// 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 <typename T>
static Status LoadStaticObject(const ConfigOptions& config_options,
- const std::string& value,
- const StaticFactoryFunc<T>& func, T** result) {
+ const std::string& value, T** result) {
std::string id;
std::unordered_map<std::string, std::string> 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
} else if (id == kNullptrString) {
result->reset();
} else {
- s = LoadSharedObject<Statistics>(config_options, id, nullptr, result);
+ s = LoadSharedObject<Statistics>(config_options, id, result);
}
return s;
}
BOptions opts_;
};
-static bool LoadSharedB(const std::string& id,
- std::shared_ptr<TestCustomizable>* 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*/) {
A_count++;
return guard->get();
});
+ library.AddFactory<TestCustomizable>(
+ "B", [](const std::string& name, std::unique_ptr<TestCustomizable>* guard,
+ std::string* /* msg */) {
+ guard->reset(new BCustomizable(name));
+ return guard->get();
+ });
library.AddFactory<TestCustomizable>(
"S", [](const std::string& name,
Status TestCustomizable::CreateFromString(
const ConfigOptions& config_options, const std::string& value,
std::shared_ptr<TestCustomizable>* result) {
- return LoadSharedObject<TestCustomizable>(config_options, value, LoadSharedB,
- result);
+ return LoadSharedObject<TestCustomizable>(config_options, value, result);
}
Status TestCustomizable::CreateFromString(
const ConfigOptions& config_options, const std::string& value,
std::unique_ptr<TestCustomizable>* result) {
- return LoadUniqueObject<TestCustomizable>(
- config_options, value,
- [](const std::string& id, std::unique_ptr<TestCustomizable>* 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<TestCustomizable>(config_options, value, result);
}
Status TestCustomizable::CreateFromString(const ConfigOptions& config_options,
const std::string& value,
TestCustomizable** result) {
- return LoadStaticObject<TestCustomizable>(
- 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<TestCustomizable>(config_options, value, result);
}
class CustomizableTest : public testing::Test {
std::unique_ptr<TestCustomizable> unique;
TestCustomizable* pointer = nullptr;
ignore.ignore_unsupported_options = false;
- ASSERT_NOK(
- LoadSharedObject<TestCustomizable>(ignore, "Unknown", nullptr, &shared));
- ASSERT_NOK(
- LoadUniqueObject<TestCustomizable>(ignore, "Unknown", nullptr, &unique));
- ASSERT_NOK(
- LoadStaticObject<TestCustomizable>(ignore, "Unknown", nullptr, &pointer));
+ ASSERT_NOK(LoadSharedObject<TestCustomizable>(ignore, "Unknown", &shared));
+ ASSERT_NOK(LoadUniqueObject<TestCustomizable>(ignore, "Unknown", &unique));
+ ASSERT_NOK(LoadStaticObject<TestCustomizable>(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<TestCustomizable>(ignore, "Unknown", nullptr, &shared));
- ASSERT_OK(
- LoadUniqueObject<TestCustomizable>(ignore, "Unknown", nullptr, &unique));
- ASSERT_OK(
- LoadStaticObject<TestCustomizable>(ignore, "Unknown", nullptr, &pointer));
+ ASSERT_OK(LoadSharedObject<TestCustomizable>(ignore, "Unknown", &shared));
+ ASSERT_OK(LoadUniqueObject<TestCustomizable>(ignore, "Unknown", &unique));
+ ASSERT_OK(LoadStaticObject<TestCustomizable>(ignore, "Unknown", &pointer));
ASSERT_EQ(shared.get(), nullptr);
ASSERT_EQ(unique.get(), nullptr);
ASSERT_EQ(pointer, nullptr);
- ASSERT_OK(LoadSharedObject<TestCustomizable>(ignore, "id=Unknown", nullptr,
- &shared));
- ASSERT_OK(LoadUniqueObject<TestCustomizable>(ignore, "id=Unknown", nullptr,
- &unique));
- ASSERT_OK(LoadStaticObject<TestCustomizable>(ignore, "id=Unknown", nullptr,
- &pointer));
+ ASSERT_OK(LoadSharedObject<TestCustomizable>(ignore, "id=Unknown", &shared));
+ ASSERT_OK(LoadUniqueObject<TestCustomizable>(ignore, "id=Unknown", &unique));
+ ASSERT_OK(LoadStaticObject<TestCustomizable>(ignore, "id=Unknown", &pointer));
ASSERT_EQ(shared.get(), nullptr);
ASSERT_EQ(unique.get(), nullptr);
ASSERT_EQ(pointer, nullptr);
ASSERT_OK(LoadSharedObject<TestCustomizable>(ignore, "id=Unknown;option=bad",
- nullptr, &shared));
+ &shared));
ASSERT_OK(LoadUniqueObject<TestCustomizable>(ignore, "id=Unknown;option=bad",
- nullptr, &unique));
+ &unique));
ASSERT_OK(LoadStaticObject<TestCustomizable>(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<TestCustomizable> shared;
- std::unique_ptr<TestCustomizable> 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) {
return 2;
}
-static bool LoadFlushPolicyFactory(
- const std::string& id, std::shared_ptr<FlushBlockPolicyFactory>* result) {
- if (id.empty()) {
- result->reset(new FlushBlockBySizePolicyFactory());
- } else {
- return false;
- }
- return true;
-}
-
FlushBlockBySizePolicyFactory::FlushBlockBySizePolicyFactory()
: FlushBlockPolicyFactory() {}
std::call_once(once, [&]() {
RegisterFlushBlockPolicyFactories(*(ObjectLibrary::Default().get()), "");
});
- return LoadSharedObject<FlushBlockPolicyFactory>(
- config_options, value, LoadFlushPolicyFactory, factory);
+
+ if (value.empty()) {
+ factory->reset(new FlushBlockBySizePolicyFactory());
+ return Status::OK();
+ } else {
+ return LoadSharedObject<FlushBlockPolicyFactory>(config_options, value,
+ factory);
+ }
}
} // namespace ROCKSDB_NAMESPACE
});
}
-static bool LoadFactory(const std::string& name,
- std::shared_ptr<TableFactory>* 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<TableFactory>* factory) {
RegisterTableFactories("");
- return LoadSharedObject<TableFactory>(config_options, value, LoadFactory,
- factory);
+ return LoadSharedObject<TableFactory>(config_options, value, factory);
}
} // namespace ROCKSDB_NAMESPACE
*result = GetFileChecksumGenCrc32cFactory();
return Status::OK();
} else {
- Status s = LoadSharedObject<FileChecksumGenFactory>(options, value, nullptr,
- result);
+ Status s = LoadSharedObject<FileChecksumGenFactory>(options, value, result);
return s;
}
}
RegisterBuiltinCompactionFilters(*(ObjectLibrary::Default().get()), "");
});
CompactionFilter* filter = const_cast<CompactionFilter*>(*result);
- Status status = LoadStaticObject<CompactionFilter>(config_options, value,
- nullptr, &filter);
+ Status status =
+ LoadStaticObject<CompactionFilter>(config_options, value, &filter);
if (status.ok()) {
*result = const_cast<CompactionFilter*>(filter);
}
std::shared_ptr<CompactionFilterFactory>* result) {
// Currently there are no builtin CompactionFilterFactories.
// If any are introduced, they need to be registered here.
- Status status = LoadSharedObject<CompactionFilterFactory>(
- config_options, value, nullptr, result);
+ Status status =
+ LoadSharedObject<CompactionFilterFactory>(config_options, value, result);
return status;
}
} // namespace ROCKSDB_NAMESPACE
#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<MergeOperator>* 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;
guard->reset(new BytesXOROperator());
return guard->get();
});
+ library.AddFactory<MergeOperator>(
+ ObjectLibrary::PatternEntry(UInt64AddOperator::kClassName())
+ .AnotherName(UInt64AddOperator::kNickName()),
+ [](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
+ std::string* /*errmsg*/) {
+ guard->reset(new UInt64AddOperator());
+ return guard->get();
+ });
+ library.AddFactory<MergeOperator>(
+ ObjectLibrary::PatternEntry(MaxOperator::kClassName())
+ .AnotherName(MaxOperator::kNickName()),
+ [](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
+ std::string* /*errmsg*/) {
+ guard->reset(new MaxOperator());
+ return guard->get();
+ });
+ library.AddFactory<MergeOperator>(
+ ObjectLibrary::PatternEntry(PutOperatorV2::kClassName())
+ .AnotherName(PutOperatorV2::kNickName()),
+ [](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
+ std::string* /*errmsg*/) {
+ guard->reset(new PutOperatorV2());
+ return guard->get();
+ });
+ library.AddFactory<MergeOperator>(
+ ObjectLibrary::PatternEntry(PutOperator::kNickName()),
+ [](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
+ std::string* /*errmsg*/) {
+ guard->reset(new PutOperator());
+ return guard->get();
+ });
return static_cast<int>(library.GetFactoryCount(&num_types));
}
std::call_once(once, [&]() {
RegisterBuiltinMergeOperators(*(ObjectLibrary::Default().get()), "");
});
- return LoadSharedObject<MergeOperator>(config_options, value,
- LoadMergeOperator, result);
+ return LoadSharedObject<MergeOperator>(config_options, value, result);
}
std::shared_ptr<MergeOperator> MergeOperators::CreateFromStringId(
#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<Slice>& 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<Slice>& 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<MergeOperator> MergeOperators::CreateMaxOperator() {
return std::make_shared<MaxOperator>();
--- /dev/null
+// 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<Slice>& operand_list,
+ std::string* new_value,
+ Logger* /*logger*/) const override;
+};
+
+} // namespace ROCKSDB_NAMESPACE
#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,
// 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<std::string>& 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<Slice>& 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<std::string>& /*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<std::string>& 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<Slice>& 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<std::string>& /*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<MergeOperator> MergeOperators::CreateDeprecatedPutOperator() {
return std::make_shared<PutOperator>();
--- /dev/null
+// 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<std::string>& 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<Slice>& 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<std::string>& /*operand_sequence*/,
+ std::string* /*new_value*/, Logger* /*logger*/) const override;
+
+ bool FullMergeV2(const MergeOperationInput& merge_in,
+ MergeOperationOutput* merge_out) const override;
+};
+
+} // namespace ROCKSDB_NAMESPACE
// 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 <memory>
#include "logging/logging.h"
#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<MergeOperator> MergeOperators::CreateUInt64AddOperator() {
return std::make_shared<UInt64AddOperator>();
--- /dev/null
+// 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
"");
});
return LoadSharedObject<TablePropertiesCollectorFactory>(options, value,
- nullptr, result);
+ result);
}
} // namespace ROCKSDB_NAMESPACE
Status WalFilter::CreateFromString(const ConfigOptions& config_options,
const std::string& value,
WalFilter** filter) {
- Status s =
- LoadStaticObject<WalFilter>(config_options, value, nullptr, filter);
+ Status s = LoadStaticObject<WalFilter>(config_options, value, filter);
return s;
}