Revert "Make Comparator into a Customizable Object (#8336)"

This reverts commit 6ad0810393.
This commit is contained in:
Andrew Kryczka 2021-06-23 15:02:20 -07:00
parent 6fc2818ef8
commit 6ee0acdbb4
8 changed files with 44 additions and 152 deletions

View File

@ -10,7 +10,6 @@
#include <string> #include <string>
#include "rocksdb/customizable.h"
#include "rocksdb/rocksdb_namespace.h" #include "rocksdb/rocksdb_namespace.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -21,7 +20,7 @@ class Slice;
// used as keys in an sstable or a database. A Comparator implementation // used as keys in an sstable or a database. A Comparator implementation
// must be thread-safe since rocksdb may invoke its methods concurrently // must be thread-safe since rocksdb may invoke its methods concurrently
// from multiple threads. // from multiple threads.
class Comparator : public Customizable { class Comparator {
public: public:
Comparator() : timestamp_size_(0) {} Comparator() : timestamp_size_(0) {}
@ -38,11 +37,7 @@ class Comparator : public Customizable {
virtual ~Comparator() {} virtual ~Comparator() {}
static Status CreateFromString(const ConfigOptions& opts,
const std::string& id,
const Comparator** comp);
static const char* Type() { return "Comparator"; } static const char* Type() { return "Comparator"; }
// Three-way comparison. Returns value: // Three-way comparison. Returns value:
// < 0 iff "a" < "b", // < 0 iff "a" < "b",
// == 0 iff "a" == "b", // == 0 iff "a" == "b",

View File

@ -8,7 +8,6 @@
#pragma once #pragma once
#include <atomic>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
@ -270,7 +269,7 @@ class Configurable {
protected: protected:
// True once the object is prepared. Once the object is prepared, only // True once the object is prepared. Once the object is prepared, only
// mutable options can be configured. // mutable options can be configured.
std::atomic<bool> prepared_; bool prepared_;
// Returns the raw pointer for the associated named option. // Returns the raw pointer for the associated named option.
// The name is typically the name of an option registered via the // The name is typically the name of an option registered via the

View File

@ -35,6 +35,7 @@ enum class OptionType {
kCompactionPri, kCompactionPri,
kSliceTransform, kSliceTransform,
kCompressionType, kCompressionType,
kComparator,
kCompactionFilter, kCompactionFilter,
kCompactionFilterFactory, kCompactionFilterFactory,
kCompactionStopStyle, kCompactionStopStyle,

View File

@ -535,30 +535,22 @@ static std::unordered_map<std::string, OptionTypeInfo>
OptionVerificationType::kNormal, OptionTypeFlags::kNone, OptionVerificationType::kNormal, OptionTypeFlags::kNone,
{0, OptionType::kCompressionType})}, {0, OptionType::kCompressionType})},
{"comparator", {"comparator",
OptionTypeInfo::AsCustomRawPtr<const Comparator>( {offset_of(&ImmutableCFOptions::user_comparator),
offset_of(&ImmutableCFOptions::user_comparator), OptionType::kComparator, OptionVerificationType::kByName,
OptionVerificationType::kByName, OptionTypeFlags::kCompareLoose, OptionTypeFlags::kCompareLoose,
// Serializes a Comparator // Parses the string and sets the corresponding comparator
[](const ConfigOptions& /*opts*/, const std::string&, [](const ConfigOptions& opts, const std::string& /*name*/,
const void* addr, std::string* value) { const std::string& value, void* addr) {
// it's a const pointer of const Comparator* auto old_comparator = static_cast<const Comparator**>(addr);
const auto* ptr = static_cast<const Comparator* const*>(addr); const Comparator* new_comparator = *old_comparator;
Status status =
// Since the user-specified comparator will be wrapped by opts.registry->NewStaticObject(value, &new_comparator);
// InternalKeyComparator, we should persist the user-specified if (status.ok()) {
// one instead of InternalKeyComparator. *old_comparator = new_comparator;
if (*ptr == nullptr) { return status;
*value = kNullptrString;
} else {
const Comparator* root_comp = (*ptr)->GetRootComparator();
if (root_comp == nullptr) {
root_comp = (*ptr);
}
*value = root_comp->Name();
} }
return Status::OK(); return Status::OK();
}, }}},
/* Use the default match function*/ nullptr)},
{"memtable_insert_with_hint_prefix_extractor", {"memtable_insert_with_hint_prefix_extractor",
{offset_of( {offset_of(
&ImmutableCFOptions::memtable_insert_with_hint_prefix_extractor), &ImmutableCFOptions::memtable_insert_with_hint_prefix_extractor),

View File

@ -771,15 +771,6 @@ static int RegisterTestObjects(ObjectLibrary& library,
guard->reset(new mock::MockTableFactory()); guard->reset(new mock::MockTableFactory());
return guard->get(); return guard->get();
}); });
library.Register<const Comparator>(
test::SimpleSuffixReverseComparator::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const Comparator>* /*guard*/,
std::string* /* errmsg */) {
static test::SimpleSuffixReverseComparator ssrc;
return &ssrc;
});
return static_cast<int>(library.GetFactoryCount(&num_types)); return static_cast<int>(library.GetFactoryCount(&num_types));
} }
@ -789,7 +780,6 @@ static int RegisterLocalObjects(ObjectLibrary& library,
// Load any locally defined objects here // Load any locally defined objects here
return static_cast<int>(library.GetFactoryCount(&num_types)); return static_cast<int>(library.GetFactoryCount(&num_types));
} }
#endif // !ROCKSDB_LITE
class LoadCustomizableTest : public testing::Test { class LoadCustomizableTest : public testing::Test {
public: public:
@ -829,31 +819,7 @@ TEST_F(LoadCustomizableTest, LoadTableFactoryTest) {
ASSERT_STREQ(factory->Name(), "MockTable"); ASSERT_STREQ(factory->Name(), "MockTable");
} }
} }
#endif // !ROCKSDB_LITE
TEST_F(LoadCustomizableTest, LoadComparatorTest) {
const Comparator* bytewise = BytewiseComparator();
const Comparator* reverse = ReverseBytewiseComparator();
const Comparator* result = nullptr;
ASSERT_NOK(Comparator::CreateFromString(
config_options_, test::SimpleSuffixReverseComparator::kClassName(),
&result));
ASSERT_OK(
Comparator::CreateFromString(config_options_, bytewise->Name(), &result));
ASSERT_EQ(result, bytewise);
ASSERT_OK(
Comparator::CreateFromString(config_options_, reverse->Name(), &result));
ASSERT_EQ(result, reverse);
if (RegisterTests("Test")) {
ASSERT_OK(Comparator::CreateFromString(
config_options_, test::SimpleSuffixReverseComparator::kClassName(),
&result));
ASSERT_NE(result, nullptr);
ASSERT_STREQ(result->Name(),
test::SimpleSuffixReverseComparator::kClassName());
}
}
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE
int main(int argc, char** argv) { int main(int argc, char** argv) {

View File

@ -562,6 +562,23 @@ bool SerializeSingleOptionHelper(const void* opt_address,
: kNullptrString; : kNullptrString;
break; break;
} }
case OptionType::kComparator: {
// it's a const pointer of const Comparator*
const auto* ptr = static_cast<const Comparator* const*>(opt_address);
// Since the user-specified comparator will be wrapped by
// InternalKeyComparator, we should persist the user-specified one
// instead of InternalKeyComparator.
if (*ptr == nullptr) {
*value = kNullptrString;
} else {
const Comparator* root_comp = (*ptr)->GetRootComparator();
if (root_comp == nullptr) {
root_comp = (*ptr);
}
*value = root_comp->Name();
}
break;
}
case OptionType::kCompactionFilter: { case OptionType::kCompactionFilter: {
// it's a const pointer of const CompactionFilter* // it's a const pointer of const CompactionFilter*
const auto* ptr = const auto* ptr =

View File

@ -98,8 +98,10 @@ class PlainInternalKeyComparator : public InternalKeyComparator {
class SimpleSuffixReverseComparator : public Comparator { class SimpleSuffixReverseComparator : public Comparator {
public: public:
SimpleSuffixReverseComparator() {} SimpleSuffixReverseComparator() {}
static const char* kClassName() { return "SimpleSuffixReverseComparator"; }
virtual const char* Name() const override { return kClassName(); } virtual const char* Name() const override {
return "SimpleSuffixReverseComparator";
}
virtual int Compare(const Slice& a, const Slice& b) const override { virtual int Compare(const Slice& a, const Slice& b) const override {
Slice prefix_a = Slice(a.data(), 8); Slice prefix_a = Slice(a.data(), 8);

View File

@ -8,17 +8,11 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "rocksdb/comparator.h" #include "rocksdb/comparator.h"
#include <stdint.h> #include <stdint.h>
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
#include <mutex>
#include "options/configurable_helper.h"
#include "port/port.h" #include "port/port.h"
#include "rocksdb/slice.h" #include "rocksdb/slice.h"
#include "rocksdb/utilities/object_registry.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -26,8 +20,8 @@ namespace {
class BytewiseComparatorImpl : public Comparator { class BytewiseComparatorImpl : public Comparator {
public: public:
BytewiseComparatorImpl() { } BytewiseComparatorImpl() { }
static const char* kClassName() { return "leveldb.BytewiseComparator"; }
const char* Name() const override { return kClassName(); } const char* Name() const override { return "leveldb.BytewiseComparator"; }
int Compare(const Slice& a, const Slice& b) const override { int Compare(const Slice& a, const Slice& b) const override {
return a.compare(b); return a.compare(b);
@ -145,10 +139,9 @@ class ReverseBytewiseComparatorImpl : public BytewiseComparatorImpl {
public: public:
ReverseBytewiseComparatorImpl() { } ReverseBytewiseComparatorImpl() { }
static const char* kClassName() { const char* Name() const override {
return "rocksdb.ReverseBytewiseComparator"; return "rocksdb.ReverseBytewiseComparator";
} }
const char* Name() const override { return kClassName(); }
int Compare(const Slice& a, const Slice& b) const override { int Compare(const Slice& a, const Slice& b) const override {
return -a.compare(b); return -a.compare(b);
@ -227,77 +220,4 @@ const Comparator* ReverseBytewiseComparator() {
return &rbytewise; return &rbytewise;
} }
#ifndef ROCKSDB_LITE
static int RegisterBuiltinComparators(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<const Comparator>(
BytewiseComparatorImpl::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const Comparator>* /*guard */,
std::string* /* errmsg */) { return BytewiseComparator(); });
library.Register<const Comparator>(
ReverseBytewiseComparatorImpl::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const Comparator>* /*guard */,
std::string* /* errmsg */) { return ReverseBytewiseComparator(); });
return 2;
}
#endif // ROCKSDB_LITE
Status Comparator::CreateFromString(const ConfigOptions& config_options,
const std::string& value,
const Comparator** result) {
#ifndef ROCKSDB_LITE
static std::once_flag once;
std::call_once(once, [&]() {
RegisterBuiltinComparators(*(ObjectLibrary::Default().get()), "");
});
#endif // ROCKSDB_LITE
std::string id;
std::unordered_map<std::string, std::string> opt_map;
Status status =
ConfigurableHelper::GetOptionsMap(value, *result, &id, &opt_map);
if (!status.ok()) { // GetOptionsMap failed
return status;
}
std::string curr_opts;
#ifndef ROCKSDB_LITE
if (*result != nullptr && (*result)->GetId() == id) {
// Try to get the existing options, ignoring any errors
ConfigOptions embedded = config_options;
embedded.delimiter = ";";
(*result)->GetOptionString(embedded, &curr_opts).PermitUncheckedError();
}
#endif
if (id == BytewiseComparatorImpl::kClassName()) {
*result = BytewiseComparator();
} else if (id == ReverseBytewiseComparatorImpl::kClassName()) {
*result = ReverseBytewiseComparator();
} else if (value.empty()) {
// No Id and no options. Clear the object
*result = nullptr;
return Status::OK();
} else if (id.empty()) { // We have no Id but have options. Not good
return Status::NotSupported("Cannot reset object ", id);
} else {
#ifndef ROCKSDB_LITE
status = config_options.registry->NewStaticObject(id, result);
#else
status = Status::NotSupported("Cannot load object in LITE mode ", id);
#endif // ROCKSDB_LITE
if (!status.ok()) {
if (config_options.ignore_unsupported_options &&
status.IsNotSupported()) {
return Status::OK();
} else {
return status;
}
} else if (!curr_opts.empty() || !opt_map.empty()) {
Comparator* comparator = const_cast<Comparator*>(*result);
status = ConfigurableHelper::ConfigureNewObject(
config_options, comparator, id, curr_opts, opt_map);
}
}
return status;
}
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE