Restore Regex support for ObjectLibrary::Register, rename new APIs to allow old one to be deprecated in the future (#9362)

Summary:
In order to support old-style regex function registration, restored the original "Register<T>(string, Factory)" method using regular expressions.  The PatternEntry methods were left in place but renamed to AddFactory.  The goal is to allow for the deprecation of the original regex Registry method in an upcoming release.

Added modes to the PatternEntry kMatchZeroOrMore and kMatchAtLeastOne to match * or +, respectively (kMatchAtLeastOne was the original behavior).

Pull Request resolved: https://github.com/facebook/rocksdb/pull/9362

Reviewed By: pdillinger

Differential Revision: D33432562

Pulled By: mrambacher

fbshipit-source-id: ed88ab3f9a2ad0d525c7bd1692873f9bb3209d02
This commit is contained in:
mrambacher 2022-01-11 06:32:42 -08:00 committed by Facebook GitHub Bot
parent 6bab278291
commit 1973fcba11
28 changed files with 310 additions and 183 deletions

View File

@ -4,6 +4,7 @@
* Added values to `TraceFilterType`: `kTraceFilterIteratorSeek`, `kTraceFilterIteratorSeekForPrev`, and `kTraceFilterMultiGet`. They can be set in `TraceOptions` to filter out the operation types after which they are named.
* Added `TraceOptions::preserve_write_order`. When enabled it guarantees write records are traced in the same order they are logged to WAL and applied to the DB. By default it is disabled (false) to match the legacy behavior and prevent regression.
* Made the Env class extend the Customizable class. Implementations need to be registered with the ObjectRegistry and to implement a Name() method in order to be created via this method.
* Add ObjectLibrary::AddFactory and ObjectLibrary::PatternEntry classes. This method and associated class are the preferred mechanism for registering factories with the ObjectLibrary going forward. The ObjectLibrary::Register method, which uses regular expressions and may be problematic, is deprecated and will be in a future release.
### Behavior Changes
* `DB::DestroyColumnFamilyHandle()` will return Status::InvalidArgument() if called with `DB::DefaultColumnFamily()`.

View File

@ -62,7 +62,7 @@ std::shared_ptr<SstPartitionerFactory> NewSstPartitionerFixedPrefixFactory(
namespace {
static int RegisterSstPartitionerFactories(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<SstPartitionerFactory>(
library.AddFactory<SstPartitionerFactory>(
SstPartitionerFixedPrefixFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<SstPartitionerFactory>* guard,

10
env/env.cc vendored
View File

@ -33,13 +33,13 @@ namespace {
#ifndef ROCKSDB_LITE
static int RegisterBuiltinEnvs(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<Env>(MockEnv::kClassName(), [](const std::string& /*uri*/,
std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
library.AddFactory<Env>(MockEnv::kClassName(), [](const std::string& /*uri*/,
std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(MockEnv::Create(Env::Default()));
return guard->get();
});
library.Register<Env>(
library.AddFactory<Env>(
CompositeEnvWrapper::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
@ -1294,7 +1294,7 @@ std::string SystemClockWrapper::SerializeOptions(
#ifndef ROCKSDB_LITE
static int RegisterBuiltinSystemClocks(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<SystemClock>(
library.AddFactory<SystemClock>(
EmulatedSystemClock::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<SystemClock>* guard,
std::string* /* errmsg */) {

View File

@ -1275,7 +1275,7 @@ static void RegisterEncryptionBuiltins() {
std::call_once(once, [&]() {
auto lib = ObjectRegistry::Default()->AddLibrary("encryption");
// Match "CTR" or "CTR://test"
lib->Register<EncryptionProvider>(
lib->AddFactory<EncryptionProvider>(
ObjectLibrary::PatternEntry(CTREncryptionProvider::kClassName(), true)
.AddSuffix("://test"),
[](const std::string& uri, std::unique_ptr<EncryptionProvider>* guard,
@ -1290,7 +1290,7 @@ static void RegisterEncryptionBuiltins() {
return guard->get();
});
lib->Register<EncryptionProvider>(
lib->AddFactory<EncryptionProvider>(
"1://test", [](const std::string& /*uri*/,
std::unique_ptr<EncryptionProvider>* guard,
std::string* /*errmsg*/) {
@ -1301,7 +1301,7 @@ static void RegisterEncryptionBuiltins() {
});
// Match "ROT13" or "ROT13:[0-9]+"
lib->Register<BlockCipher>(
lib->AddFactory<BlockCipher>(
ObjectLibrary::PatternEntry(ROT13BlockCipher::kClassName(), true)
.AddNumber(":"),
[](const std::string& uri, std::unique_ptr<BlockCipher>* guard,

15
env/env_test.cc vendored
View File

@ -2492,7 +2492,7 @@ TEST_F(CreateEnvTest, CreateDefaultSystemClock) {
TEST_F(CreateEnvTest, CreateMockSystemClock) {
std::shared_ptr<SystemClock> mock, copy;
config_options_.registry->AddLibrary("test")->Register<SystemClock>(
config_options_.registry->AddLibrary("test")->AddFactory<SystemClock>(
MockSystemClock::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<SystemClock>* guard,
std::string* /* errmsg */) {
@ -2939,12 +2939,13 @@ class WrappedEnv : public EnvWrapper {
static const char* kClassName() { return "WrappedEnv"; }
const char* Name() const override { return kClassName(); }
static void Register(ObjectLibrary& lib, const std::string& /*arg*/) {
lib.Register<Env>(WrappedEnv::kClassName(), [](const std::string& /*uri*/,
std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(nullptr));
return guard->get();
});
lib.AddFactory<Env>(
WrappedEnv::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(nullptr));
return guard->get();
});
}
};
} // namespace

10
env/file_system.cc vendored
View File

@ -32,21 +32,21 @@ Status FileSystem::Load(const std::string& value,
#ifndef ROCKSDB_LITE
static int RegisterBuiltinFileSystems(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<FileSystem>(
library.AddFactory<FileSystem>(
TimedFileSystem::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
std::string* /* errmsg */) {
guard->reset(new TimedFileSystem(nullptr));
return guard->get();
});
library.Register<FileSystem>(
library.AddFactory<FileSystem>(
ReadOnlyFileSystem::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
std::string* /* errmsg */) {
guard->reset(new ReadOnlyFileSystem(nullptr));
return guard->get();
});
library.Register<FileSystem>(
library.AddFactory<FileSystem>(
EncryptedFileSystem::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
std::string* errmsg) {
@ -56,7 +56,7 @@ static int RegisterBuiltinFileSystems(ObjectLibrary& library,
}
return guard->get();
});
library.Register<FileSystem>(
library.AddFactory<FileSystem>(
MockFileSystem::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
std::string* /*errmsg*/) {
@ -64,7 +64,7 @@ static int RegisterBuiltinFileSystems(ObjectLibrary& library,
return guard->get();
});
#ifndef OS_WIN
library.Register<FileSystem>(
library.AddFactory<FileSystem>(
ChrootFileSystem::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
std::string* /* errmsg */) {

4
env/fs_posix.cc vendored
View File

@ -1124,8 +1124,8 @@ std::shared_ptr<FileSystem> FileSystem::Default() {
#ifndef ROCKSDB_LITE
static FactoryFunc<FileSystem> posix_filesystem_reg =
ObjectLibrary::Default()->Register<FileSystem>(
"posix://.*",
ObjectLibrary::Default()->AddFactory<FileSystem>(
ObjectLibrary::PatternEntry("posix").AddSeparator("://", false),
[](const std::string& /* uri */, std::unique_ptr<FileSystem>* f,
std::string* /* errmsg */) {
f->reset(new PosixFileSystem());

View File

@ -16,6 +16,7 @@
#include <vector>
#include "rocksdb/status.h"
#include "rocksdb/utilities/regex.h"
namespace ROCKSDB_NAMESPACE {
class Customizable;
@ -41,17 +42,48 @@ template <typename T>
using ConfigureFunc = std::function<Status(T*)>;
class ObjectLibrary {
private:
// Base class for an Entry in the Registry.
class Entry {
public:
virtual ~Entry() {}
virtual bool Matches(const std::string& target) const = 0;
virtual const char* Name() const = 0;
};
// A class that implements an Entry based on Regex.
//
// WARNING: some regexes are problematic for std::regex; see
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582 for example
//
// This class is deprecated and will be removed in a future release
class RegexEntry : public Entry {
public:
explicit RegexEntry(const std::string& name) : name_(name) {
Regex::Parse(name, &regex_).PermitUncheckedError();
}
bool Matches(const std::string& target) const override {
return regex_.Matches(target);
}
const char* Name() const override { return name_.c_str(); }
private:
std::string name_;
Regex regex_; // The pattern for this entry
};
public:
// Class for matching target strings to a pattern.
// Entries consist of a name that starts the pattern and attributes
// The following attributes can be added to the entry:
// -Suffix: Comparable to name(suffix)
// -Separator: Comparable to name(separator).+
// -Separator: Comparable to name(separator).+ or name(separator).*
// -Number: Comparable to name(separator).[0-9]+
// -AltName: Comparable to (name|alt)
// -Optional: Comparable to name(separator)?
// Multiple separators can be combined and cause multiple matches.
// For example, Pattern("A").AnotherName("B"),AddSeparator("@").AddNumber("#")
// For example, Pattern("A").AnotherName("B").AddSeparator("@").AddNumber("#")
// is roughly equivalent to "(A|B)@.+#.+"
//
// Note that though this class does provide some regex-style matching,
@ -60,12 +92,13 @@ class ObjectLibrary {
// Name("Hello").AddSeparator(" ").AddSuffix("!") would match
// "Hello world!", but not "Hello world!!"
// - No backtracking is necessary, enabling reliably efficient matching
class PatternEntry {
class PatternEntry : public Entry {
private:
enum Quantifier {
kMatchPattern, // [suffix].+
kMatchExact, // [suffix]
kMatchNumeric, // [suffix][0-9]+
kMatchZeroOrMore, // [suffix].*
kMatchAtLeastOne, // [suffix].+
kMatchExact, // [suffix]
kMatchNumeric, // [suffix][0-9]+
};
public:
@ -78,7 +111,7 @@ class ObjectLibrary {
return entry;
}
// Creates a new pattern entry for "name". If optional is true,
// Creates a new PatternEntry for "name". If optional is true,
// Matches will also return true if name==target
explicit PatternEntry(const std::string& name, bool optional = true)
: name_(name), optional_(optional), slength_(0) {
@ -95,9 +128,19 @@ class ObjectLibrary {
// Adds a separator (exact match of separator with trailing characters) to
// the entry
PatternEntry& AddSeparator(const std::string& separator) {
separators_.emplace_back(separator, kMatchPattern);
slength_ += separator.size() + 1;
// If at_least_one is true, the separator must be followed by at least
// one character (e.g. separator.+).
// If at_least_one is false, the separator may be followed by zero or
// more characters (e.g. separator.*).
PatternEntry& AddSeparator(const std::string& separator,
bool at_least_one = true) {
slength_ += separator.size();
if (at_least_one) {
separators_.emplace_back(separator, kMatchAtLeastOne);
++slength_;
} else {
separators_.emplace_back(separator, kMatchZeroOrMore);
}
return *this;
}
@ -124,8 +167,8 @@ class ObjectLibrary {
}
// Checks to see if the target matches this entry
bool Matches(const std::string& target) const;
const char* Name() const { return name_.c_str(); }
bool Matches(const std::string& target) const override;
const char* Name() const override { return name_.c_str(); }
private:
size_t MatchSeparatorAt(size_t start, Quantifier mode,
@ -144,24 +187,16 @@ class ObjectLibrary {
}; // End class Entry
private:
// Base class for an Entry in the Registry.
class Entry {
public:
virtual ~Entry() {}
virtual bool Matches(const std::string& target) const = 0;
virtual const char* Name() const = 0;
};
// An Entry containing a FactoryFunc for creating new Objects
template <typename T>
class FactoryEntry : public Entry {
public:
FactoryEntry(const PatternEntry& e, FactoryFunc<T> f)
FactoryEntry(Entry* e, FactoryFunc<T> f)
: entry_(e), factory_(std::move(f)) {}
bool Matches(const std::string& target) const override {
return entry_.Matches(target);
return entry_->Matches(target);
}
const char* Name() const override { return entry_.Name(); }
const char* Name() const override { return entry_->Name(); }
// Creates a new T object.
T* NewFactoryObject(const std::string& target, std::unique_ptr<T>* guard,
@ -171,7 +206,7 @@ class ObjectLibrary {
const FactoryFunc<T>& GetFactory() const { return factory_; }
private:
PatternEntry entry_; // The pattern for this entry
std::unique_ptr<Entry> entry_; // What to match for this entry
FactoryFunc<T> factory_;
}; // End class FactoryEntry
public:
@ -179,13 +214,16 @@ class ObjectLibrary {
const std::string& GetID() const { return id_; }
// Finds the factory function for the input target.
// @see PatternEntry for the matching rules to target
// @return If matched, the FactoryFunc for this target, else nullptr
template <typename T>
FactoryFunc<T> FindFactory(const std::string& pattern) const {
FactoryFunc<T> FindFactory(const std::string& target) const {
std::unique_lock<std::mutex> lock(mu_);
auto factories = factories_.find(T::Type());
if (factories != factories_.end()) {
for (const auto& e : factories->second) {
if (e->Matches(pattern)) {
if (e->Matches(target)) {
const auto* fe =
static_cast<const ObjectLibrary::FactoryEntry<T>*>(e.get());
return fe->GetFactory();
@ -202,22 +240,44 @@ class ObjectLibrary {
void Dump(Logger* logger) const;
// Registers the factory with the library for the pattern.
// Registers the factory with the library for the regular expression pattern.
// If the pattern matches, the factory may be used to create a new object.
//
// WARNING: some regexes are problematic for std::regex; see
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582 for example
//
// Deprecated. Will be removed in a major release. Code should use AddFactory
// instead.
template <typename T>
const FactoryFunc<T>& Register(const std::string& pattern,
const FactoryFunc<T>& factory) {
PatternEntry entry(pattern);
return Register(entry, factory);
std::unique_ptr<Entry> entry(
new FactoryEntry<T>(new RegexEntry(pattern), factory));
AddFactoryEntry(T::Type(), std::move(entry));
return factory;
}
// Registers the factory with the library for the name.
// If name==target, the factory may be used to create a new object.
template <typename T>
const FactoryFunc<T>& Register(const PatternEntry& pattern,
const FactoryFunc<T>& func) {
std::unique_ptr<Entry> entry(new FactoryEntry<T>(pattern, func));
std::unique_lock<std::mutex> lock(mu_);
auto& factories = factories_[T::Type()];
factories.emplace_back(std::move(entry));
const FactoryFunc<T>& AddFactory(const std::string& name,
const FactoryFunc<T>& func) {
std::unique_ptr<Entry> entry(
new FactoryEntry<T>(new PatternEntry(name), func));
AddFactoryEntry(T::Type(), std::move(entry));
return func;
}
// Registers the factory with the library for the entry.
// If the entry matches the target, the factory may be used to create a new
// object.
// @see PatternEntry for the matching rules.
template <typename T>
const FactoryFunc<T>& AddFactory(const PatternEntry& entry,
const FactoryFunc<T>& func) {
std::unique_ptr<Entry> factory(
new FactoryEntry<T>(new PatternEntry(entry), func));
AddFactoryEntry(T::Type(), std::move(factory));
return func;
}
@ -230,6 +290,12 @@ class ObjectLibrary {
static std::shared_ptr<ObjectLibrary>& Default();
private:
void AddFactoryEntry(const char* type, std::unique_ptr<Entry>&& entry) {
std::unique_lock<std::mutex> lock(mu_);
auto& factories = factories_[type];
factories.emplace_back(std::move(entry));
}
// Protects the entry map
mutable std::mutex mu_;
// ** FactoryFunctions for this loader, organized by type
@ -269,17 +335,16 @@ class ObjectRegistry {
library->Register(registrar, arg);
}
// Creates a new T using the factory function that was registered with a
// pattern that matches the provided "target" string according to
// std::regex_match.
//
// WARNING: some regexes are problematic for std::regex; see
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582 for example
// Creates a new T using the factory function that was registered for this
// target. Searches through the libraries to find the first library where
// there is an entry that matches target (see PatternEntry for the matching
// rules).
//
// If no registered functions match, returns nullptr. If multiple functions
// match, the factory function used is unspecified.
//
// Populates res_guard with result pointer if caller is granted ownership.
// Populates guard with result pointer if caller is granted ownership.
// Deprecated. Use NewShared/Static/UniqueObject instead.
template <typename T>
T* NewObject(const std::string& target, std::unique_ptr<T>* guard,
std::string* errmsg) {
@ -491,7 +556,7 @@ class ObjectRegistry {
const std::shared_ptr<Customizable>& c);
// Searches (from back to front) the libraries looking for the
// factory that matches this pattern.
// factory that matches this name.
// Returns the factory if it is found, and nullptr otherwise
template <typename T>
const FactoryFunc<T> FindFactory(const std::string& name) const {

View File

@ -24,14 +24,14 @@ static std::unordered_map<std::string, OptionTypeInfo> ma_wrapper_type_info = {
#ifndef ROCKSDB_LITE
static int RegisterBuiltinAllocators(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<MemoryAllocator>(
library.AddFactory<MemoryAllocator>(
DefaultMemoryAllocator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MemoryAllocator>* guard,
std::string* /*errmsg*/) {
guard->reset(new DefaultMemoryAllocator());
return guard->get();
});
library.Register<MemoryAllocator>(
library.AddFactory<MemoryAllocator>(
CountedMemoryAllocator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MemoryAllocator>* guard,
std::string* /*errmsg*/) {
@ -39,7 +39,7 @@ static int RegisterBuiltinAllocators(ObjectLibrary& library,
std::make_shared<DefaultMemoryAllocator>()));
return guard->get();
});
library.Register<MemoryAllocator>(
library.AddFactory<MemoryAllocator>(
JemallocNodumpAllocator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MemoryAllocator>* guard,
std::string* errmsg) {
@ -49,7 +49,7 @@ static int RegisterBuiltinAllocators(ObjectLibrary& library,
}
return guard->get();
});
library.Register<MemoryAllocator>(
library.AddFactory<MemoryAllocator>(
MemkindKmemAllocator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MemoryAllocator>* guard,
std::string* errmsg) {

View File

@ -288,7 +288,7 @@ std::shared_ptr<Statistics> CreateDBStatistics() {
#ifndef ROCKSDB_LITE
static int RegisterBuiltinStatistics(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<Statistics>(
library.AddFactory<Statistics>(
StatisticsImpl::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<Statistics>* guard,
std::string* /* errmsg */) {

View File

@ -180,7 +180,7 @@ static bool LoadSharedB(const std::string& id,
static int A_count = 0;
static int RegisterCustomTestObjects(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<TestCustomizable>(
library.AddFactory<TestCustomizable>(
ObjectLibrary::PatternEntry("A", true).AddSeparator("_"),
[](const std::string& name, std::unique_ptr<TestCustomizable>* guard,
std::string* /* msg */) {
@ -189,7 +189,7 @@ static int RegisterCustomTestObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<TestCustomizable>(
library.AddFactory<TestCustomizable>(
"S", [](const std::string& name,
std::unique_ptr<TestCustomizable>* /* guard */,
std::string* /* msg */) { return new BCustomizable(name); });
@ -334,7 +334,7 @@ class CustomizableTest : public testing::Test {
// - a XXX.id option
// - a property with a name
TEST_F(CustomizableTest, CreateByNameTest) {
ObjectLibrary::Default()->Register<TestCustomizable>(
ObjectLibrary::Default()->AddFactory<TestCustomizable>(
ObjectLibrary::PatternEntry("TEST", false).AddSeparator("_"),
[](const std::string& name, std::unique_ptr<TestCustomizable>* guard,
std::string* /* msg */) {
@ -565,7 +565,7 @@ TEST_F(CustomizableTest, PrepareOptionsTest) {
}
};
ObjectLibrary::Default()->Register<TestCustomizable>(
ObjectLibrary::Default()->AddFactory<TestCustomizable>(
"P",
[](const std::string& /*name*/, std::unique_ptr<TestCustomizable>* guard,
std::string* /* msg */) {
@ -1029,7 +1029,7 @@ TEST_F(CustomizableTest, FactoryFunctionTest) {
TEST_F(CustomizableTest, URLFactoryTest) {
std::unique_ptr<TestCustomizable> unique;
config_options_.registry->AddLibrary("URL")->Register<TestCustomizable>(
config_options_.registry->AddLibrary("URL")->AddFactory<TestCustomizable>(
ObjectLibrary::PatternEntry("Z", false).AddSeparator(""),
[](const std::string& name, std::unique_ptr<TestCustomizable>* guard,
std::string* /* msg */) {
@ -1186,7 +1186,7 @@ TEST_F(CustomizableTest, CreateManagedObjects) {
};
config_options_.registry->AddLibrary("Managed")
->Register<ManagedCustomizable>(
->AddFactory<ManagedCustomizable>(
ObjectLibrary::PatternEntry::AsIndividualId(
ManagedCustomizable::kClassName()),
[](const std::string& /*name*/,
@ -1445,21 +1445,21 @@ class MockRateLimiter : public RateLimiter {
static int RegisterLocalObjects(ObjectLibrary& library,
const std::string& /*arg*/) {
size_t num_types;
library.Register<TableFactory>(
library.AddFactory<TableFactory>(
mock::MockTableFactory::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<TableFactory>* guard,
std::string* /* errmsg */) {
guard->reset(new mock::MockTableFactory());
return guard->get();
});
library.Register<EventListener>(
library.AddFactory<EventListener>(
OnFileDeletionListener::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<EventListener>* guard,
std::string* /* errmsg */) {
guard->reset(new OnFileDeletionListener());
return guard->get();
});
library.Register<EventListener>(
library.AddFactory<EventListener>(
FlushCounterListener::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<EventListener>* guard,
std::string* /* errmsg */) {
@ -1467,7 +1467,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
// Load any locally defined objects here
library.Register<const SliceTransform>(
library.AddFactory<const SliceTransform>(
MockSliceTransform::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const SliceTransform>* guard,
@ -1475,7 +1475,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
guard->reset(new MockSliceTransform());
return guard->get();
});
library.Register<Statistics>(
library.AddFactory<Statistics>(
TestStatistics::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<Statistics>* guard,
std::string* /* errmsg */) {
@ -1483,7 +1483,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<EncryptionProvider>(
library.AddFactory<EncryptionProvider>(
ObjectLibrary::PatternEntry(MockEncryptionProvider::kClassName(), true)
.AddSuffix("://test"),
[](const std::string& uri, std::unique_ptr<EncryptionProvider>* guard,
@ -1491,20 +1491,21 @@ static int RegisterLocalObjects(ObjectLibrary& library,
guard->reset(new MockEncryptionProvider(uri));
return guard->get();
});
library.Register<BlockCipher>("Mock", [](const std::string& /*uri*/,
std::unique_ptr<BlockCipher>* guard,
std::string* /* errmsg */) {
guard->reset(new MockCipher());
return guard->get();
});
library.Register<MemoryAllocator>(
library.AddFactory<BlockCipher>(
"Mock",
[](const std::string& /*uri*/, std::unique_ptr<BlockCipher>* guard,
std::string* /* errmsg */) {
guard->reset(new MockCipher());
return guard->get();
});
library.AddFactory<MemoryAllocator>(
MockMemoryAllocator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MemoryAllocator>* guard,
std::string* /* errmsg */) {
guard->reset(new MockMemoryAllocator());
return guard->get();
});
library.Register<FlushBlockPolicyFactory>(
library.AddFactory<FlushBlockPolicyFactory>(
TestFlushBlockPolicyFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<FlushBlockPolicyFactory>* guard,
@ -1513,7 +1514,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<SecondaryCache>(
library.AddFactory<SecondaryCache>(
TestSecondaryCache::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<SecondaryCache>* guard,
std::string* /* errmsg */) {
@ -1521,7 +1522,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<FileSystem>(
library.AddFactory<FileSystem>(
DummyFileSystem::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
std::string* /* errmsg */) {
@ -1529,7 +1530,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<SstPartitionerFactory>(
library.AddFactory<SstPartitionerFactory>(
MockSstPartitionerFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<SstPartitionerFactory>* guard,
@ -1538,7 +1539,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<FileChecksumGenFactory>(
library.AddFactory<FileChecksumGenFactory>(
MockFileChecksumGenFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<FileChecksumGenFactory>* guard,
@ -1547,7 +1548,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<TablePropertiesCollectorFactory>(
library.AddFactory<TablePropertiesCollectorFactory>(
MockTablePropertiesCollectorFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<TablePropertiesCollectorFactory>* guard,
@ -1556,7 +1557,7 @@ static int RegisterLocalObjects(ObjectLibrary& library,
return guard->get();
});
library.Register<RateLimiter>(
library.AddFactory<RateLimiter>(
MockRateLimiter::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<RateLimiter>* guard,
std::string* /* errmsg */) {

View File

@ -388,7 +388,7 @@ TEST_F(OptionsTest, GetColumnFamilyOptionsFromStringTest) {
// Comparator from object registry
std::string kCompName = "reverse_comp";
ObjectLibrary::Default()->Register<const Comparator>(
ObjectLibrary::Default()->AddFactory<const Comparator>(
kCompName,
[](const std::string& /*name*/,
std::unique_ptr<const Comparator>* /*guard*/,
@ -1291,7 +1291,7 @@ TEST_F(OptionsTest, GetOptionsFromStringTest) {
NewBlockBasedTableFactory(block_based_table_options));
// Register an Env with object registry.
ObjectLibrary::Default()->Register<Env>(
ObjectLibrary::Default()->AddFactory<Env>(
CustomEnv::kClassName(),
[](const std::string& /*name*/, std::unique_ptr<Env>* /*env_guard*/,
std::string* /* errmsg */) {
@ -2079,7 +2079,7 @@ TEST_F(OptionsTest, OptionTablePropertiesTest) {
// Repeat the experiment. The copy should have the same
// properties as the original
cfg_opts.registry->AddLibrary("collector")
->Register<TablePropertiesCollectorFactory>(
->AddFactory<TablePropertiesCollectorFactory>(
ObjectLibrary::PatternEntry(
TestTablePropertiesCollectorFactory::kClassName(), false)
.AddSeparator(":"),
@ -2153,14 +2153,14 @@ class TestConfigEventListener : public TestEventListener {
static int RegisterTestEventListener(ObjectLibrary& library,
const std::string& arg) {
library.Register<EventListener>(
library.AddFactory<EventListener>(
"Test" + arg,
[](const std::string& name, std::unique_ptr<EventListener>* guard,
std::string* /* errmsg */) {
guard->reset(new TestEventListener(name.substr(4)));
return guard->get();
});
library.Register<EventListener>(
library.AddFactory<EventListener>(
"TestConfig" + arg,
[](const std::string& name, std::unique_ptr<EventListener>* guard,
std::string* /* errmsg */) {
@ -2195,7 +2195,7 @@ const static std::string kCustomEnvName = "Custom";
const static std::string kCustomEnvProp = "env=" + kCustomEnvName;
static int RegisterCustomEnv(ObjectLibrary& library, const std::string& arg) {
library.Register<Env>(
library.AddFactory<Env>(
arg, [](const std::string& /*name*/, std::unique_ptr<Env>* /*env_guard*/,
std::string* /* errmsg */) {
static CustomEnv env(Env::Default());
@ -2524,7 +2524,7 @@ TEST_F(OptionsOldApiTest, GetColumnFamilyOptionsFromStringTest) {
// Comparator from object registry
std::string kCompName = "reverse_comp";
ObjectLibrary::Default()->Register<const Comparator>(
ObjectLibrary::Default()->AddFactory<const Comparator>(
kCompName,
[](const std::string& /*name*/,
std::unique_ptr<const Comparator>* /*guard*/,
@ -2968,7 +2968,7 @@ TEST_F(OptionsOldApiTest, GetOptionsFromStringTest) {
NewBlockBasedTableFactory(block_based_table_options));
// Register an Env with object registry.
ObjectLibrary::Default()->Register<Env>(
ObjectLibrary::Default()->AddFactory<Env>(
"CustomEnvDefault",
[](const std::string& /*name*/, std::unique_ptr<Env>* /*env_guard*/,
std::string* /* errmsg */) {

View File

@ -94,7 +94,7 @@ FlushBlockPolicy* FlushBlockBySizePolicyFactory::NewFlushBlockPolicy(
#ifndef ROCKSDB_LITE
static int RegisterFlushBlockPolicyFactories(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<FlushBlockPolicyFactory>(
library.AddFactory<FlushBlockPolicyFactory>(
FlushBlockBySizePolicyFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<FlushBlockPolicyFactory>* guard,
@ -102,7 +102,7 @@ static int RegisterFlushBlockPolicyFactories(ObjectLibrary& library,
guard->reset(new FlushBlockBySizePolicyFactory());
return guard->get();
});
library.Register<FlushBlockPolicyFactory>(
library.AddFactory<FlushBlockPolicyFactory>(
FlushBlockEveryKeyPolicyFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<FlushBlockPolicyFactory>* guard,

View File

@ -167,7 +167,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library,
pattern.AddNumber(":");
return pattern;
};
library.Register<MemTableRepFactory>(
library.AddFactory<MemTableRepFactory>(
AsPattern(VectorRepFactory::kClassName(), VectorRepFactory::kNickName()),
[](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
std::string* /*errmsg*/) {
@ -180,7 +180,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library,
}
return guard->get();
});
library.Register<MemTableRepFactory>(
library.AddFactory<MemTableRepFactory>(
AsPattern(SkipListFactory::kClassName(), SkipListFactory::kNickName()),
[](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
std::string* /*errmsg*/) {
@ -193,7 +193,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library,
}
return guard->get();
});
library.Register<MemTableRepFactory>(
library.AddFactory<MemTableRepFactory>(
AsPattern("HashLinkListRepFactory", "hash_linkedlist"),
[](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
std::string* /*errmsg*/) {
@ -207,7 +207,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library,
}
return guard->get();
});
library.Register<MemTableRepFactory>(
library.AddFactory<MemTableRepFactory>(
AsPattern("HashSkipListRepFactory", "prefix_hash"),
[](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
std::string* /*errmsg*/) {
@ -221,7 +221,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library,
}
return guard->get();
});
library.Register<MemTableRepFactory>(
library.AddFactory<MemTableRepFactory>(
"cuckoo",
[](const std::string& /*uri*/,
std::unique_ptr<MemTableRepFactory>* /*guard*/, std::string* errmsg) {

View File

@ -20,21 +20,21 @@ static void RegisterTableFactories(const std::string& /*arg*/) {
static std::once_flag loaded;
std::call_once(loaded, []() {
auto library = ObjectLibrary::Default();
library->Register<TableFactory>(
library->AddFactory<TableFactory>(
TableFactory::kBlockBasedTableName(),
[](const std::string& /*uri*/, std::unique_ptr<TableFactory>* guard,
std::string* /* errmsg */) {
guard->reset(new BlockBasedTableFactory());
return guard->get();
});
library->Register<TableFactory>(
library->AddFactory<TableFactory>(
TableFactory::kPlainTableName(),
[](const std::string& /*uri*/, std::unique_ptr<TableFactory>* guard,
std::string* /* errmsg */) {
guard->reset(new PlainTableFactory());
return guard->get();
});
library->Register<TableFactory>(
library->AddFactory<TableFactory>(
TableFactory::kCuckooTableName(),
[](const std::string& /*uri*/, std::unique_ptr<TableFactory>* guard,
std::string* /* errmsg */) {

View File

@ -678,7 +678,7 @@ class SpecialSkipListFactory : public MemTableRepFactory {
public:
#ifndef ROCKSDB_LITE
static bool Register(ObjectLibrary& library, const std::string& /*arg*/) {
library.Register<MemTableRepFactory>(
library.AddFactory<MemTableRepFactory>(
ObjectLibrary::PatternEntry(SpecialSkipListFactory::kClassName(), true)
.AddNumber(":"),
[](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
@ -738,7 +738,7 @@ MemTableRepFactory* NewSpecialSkipListFactory(int num_entries_per_flush) {
// This method loads existing test classes into the ObjectRegistry
int RegisterTestObjects(ObjectLibrary& library, const std::string& arg) {
size_t num_types;
library.Register<const Comparator>(
library.AddFactory<const Comparator>(
test::SimpleSuffixReverseComparator::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const Comparator>* /*guard*/,
@ -747,27 +747,27 @@ int RegisterTestObjects(ObjectLibrary& library, const std::string& arg) {
return &ssrc;
});
SpecialSkipListFactory::Register(library, arg);
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
"Changling",
[](const std::string& uri, std::unique_ptr<MergeOperator>* guard,
std::string* /* errmsg */) {
guard->reset(new test::ChanglingMergeOperator(uri));
return guard->get();
});
library.Register<CompactionFilter>(
library.AddFactory<CompactionFilter>(
"Changling",
[](const std::string& uri, std::unique_ptr<CompactionFilter>* /*guard*/,
std::string* /* errmsg */) {
return new test::ChanglingCompactionFilter(uri);
});
library.Register<CompactionFilterFactory>(
library.AddFactory<CompactionFilterFactory>(
"Changling", [](const std::string& uri,
std::unique_ptr<CompactionFilterFactory>* guard,
std::string* /* errmsg */) {
guard->reset(new test::ChanglingCompactionFilterFactory(uri));
return guard->get();
});
library.Register<SystemClock>(
library.AddFactory<SystemClock>(
MockSystemClock::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<SystemClock>* guard,
std::string* /* errmsg */) {

View File

@ -231,12 +231,12 @@ const Comparator* ReverseBytewiseComparator() {
#ifndef ROCKSDB_LITE
static int RegisterBuiltinComparators(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<const Comparator>(
library.AddFactory<const Comparator>(
BytewiseComparatorImpl::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const Comparator>* /*guard */,
std::string* /* errmsg */) { return BytewiseComparator(); });
library.Register<const Comparator>(
library.AddFactory<const Comparator>(
ReverseBytewiseComparatorImpl::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const Comparator>* /*guard */,

View File

@ -138,7 +138,7 @@ Status GetFileChecksumsFromManifest(Env* src_env, const std::string& abs_path,
namespace {
static int RegisterFileChecksumGenFactories(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<FileChecksumGenFactory>(
library.AddFactory<FileChecksumGenFactory>(
FileChecksumGenCrc32cFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<FileChecksumGenFactory>* guard,

View File

@ -431,7 +431,7 @@ namespace {
#ifndef ROCKSDB_LITE
static int RegisterBuiltinRateLimiters(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<RateLimiter>(
library.AddFactory<RateLimiter>(
GenericRateLimiter::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<RateLimiter>* guard,
std::string* /*errmsg*/) {

View File

@ -146,7 +146,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library,
// For the builtin transforms, the format is typically
// [Name] or [Name].[0-9]+
// [NickName]:[0-9]+
library.Register<const SliceTransform>(
library.AddFactory<const SliceTransform>(
NoopTransform::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<const SliceTransform>* guard,
@ -154,7 +154,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library,
guard->reset(NewNoopTransform());
return guard->get();
});
library.Register<const SliceTransform>(
library.AddFactory<const SliceTransform>(
ObjectLibrary::PatternEntry(FixedPrefixTransform::kNickName(), false)
.AddNumber(":"),
[](const std::string& uri, std::unique_ptr<const SliceTransform>* guard,
@ -164,7 +164,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library,
guard->reset(NewFixedPrefixTransform(len));
return guard->get();
});
library.Register<const SliceTransform>(
library.AddFactory<const SliceTransform>(
ObjectLibrary::PatternEntry(FixedPrefixTransform::kClassName(), true)
.AddNumber("."),
[](const std::string& uri, std::unique_ptr<const SliceTransform>* guard,
@ -178,7 +178,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library,
}
return guard->get();
});
library.Register<const SliceTransform>(
library.AddFactory<const SliceTransform>(
ObjectLibrary::PatternEntry(CappedPrefixTransform::kNickName(), false)
.AddNumber(":"),
[](const std::string& uri, std::unique_ptr<const SliceTransform>* guard,
@ -188,7 +188,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library,
guard->reset(NewCappedPrefixTransform(len));
return guard->get();
});
library.Register<const SliceTransform>(
library.AddFactory<const SliceTransform>(
ObjectLibrary::PatternEntry(CappedPrefixTransform::kClassName(), true)
.AddNumber("."),
[](const std::string& uri, std::unique_ptr<const SliceTransform>* guard,

View File

@ -80,21 +80,21 @@ CassandraCompactionFilterFactory::CreateCompactionFilter(
#ifndef ROCKSDB_LITE
int RegisterCassandraObjects(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
CassandraValueMergeOperator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
std::string* /* errmsg */) {
guard->reset(new CassandraValueMergeOperator(0));
return guard->get();
});
library.Register<CompactionFilter>(
library.AddFactory<CompactionFilter>(
CassandraCompactionFilter::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<CompactionFilter>* /*guard */,
std::string* /* errmsg */) {
return new CassandraCompactionFilter(false, 0);
});
library.Register<CompactionFilterFactory>(
library.AddFactory<CompactionFilterFactory>(
CassandraCompactionFilterFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<CompactionFilterFactory>* guard,

View File

@ -16,7 +16,7 @@ namespace ROCKSDB_NAMESPACE {
#ifndef ROCKSDB_LITE
static int RegisterBuiltinCompactionFilters(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<CompactionFilter>(
library.AddFactory<CompactionFilter>(
RemoveEmptyValueCompactionFilter::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<CompactionFilter>* /*guard*/,

View File

@ -55,7 +55,7 @@ static bool LoadMergeOperator(const std::string& id,
static int RegisterBuiltinMergeOperators(ObjectLibrary& library,
const std::string& /*arg*/) {
size_t num_types;
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
ObjectLibrary::PatternEntry(StringAppendOperator::kClassName())
.AnotherName(StringAppendOperator::kNickName()),
[](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
@ -63,7 +63,7 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library,
guard->reset(new StringAppendOperator(","));
return guard->get();
});
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
ObjectLibrary::PatternEntry(StringAppendTESTOperator::kClassName())
.AnotherName(StringAppendTESTOperator::kNickName()),
[](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
@ -71,7 +71,7 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library,
guard->reset(new StringAppendTESTOperator(","));
return guard->get();
});
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
ObjectLibrary::PatternEntry(SortList::kClassName())
.AnotherName(SortList::kNickName()),
[](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
@ -79,7 +79,7 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library,
guard->reset(new SortList());
return guard->get();
});
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
ObjectLibrary::PatternEntry(BytesXOROperator::kClassName())
.AnotherName(BytesXOROperator::kNickName()),
[](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,

View File

@ -81,7 +81,7 @@ bool ObjectLibrary::PatternEntry::MatchesTarget(const std::string &name,
// unmatched in the target is acceptable.
if (mode == kMatchExact) {
return (start == tlen);
} else if (start >= tlen) {
} else if (start > tlen || (start == tlen && mode != kMatchZeroOrMore)) {
return false;
} else if (mode == kMatchNumeric) {
while (start < tlen) {

View File

@ -8,6 +8,7 @@
#include "rocksdb/utilities/object_registry.h"
#include "rocksdb/customizable.h"
#include "rocksdb/utilities/regex.h"
#include "test_util/testharness.h"
namespace ROCKSDB_NAMESPACE {
@ -19,7 +20,7 @@ class ObjRegistryTest : public testing::Test {
int ObjRegistryTest::num_a = 0;
int ObjRegistryTest::num_b = 0;
static FactoryFunc<Env> test_reg_a = ObjectLibrary::Default()->Register<Env>(
static FactoryFunc<Env> test_reg_a = ObjectLibrary::Default()->AddFactory<Env>(
ObjectLibrary::PatternEntry("a", false).AddSeparator("://"),
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*env_guard*/,
std::string* /* errmsg */) {
@ -36,7 +37,7 @@ class WrappedEnv : public EnvWrapper {
const char* Name() const override { return id_.c_str(); }
std::string GetId() const override { return id_; }
};
static FactoryFunc<Env> test_reg_b = ObjectLibrary::Default()->Register<Env>(
static FactoryFunc<Env> test_reg_b = ObjectLibrary::Default()->AddFactory<Env>(
ObjectLibrary::PatternEntry("b", false).AddSeparator("://"),
[](const std::string& uri, std::unique_ptr<Env>* env_guard,
std::string* /* errmsg */) {
@ -77,12 +78,12 @@ TEST_F(ObjRegistryTest, LocalRegistry) {
std::shared_ptr<ObjectLibrary> library =
std::make_shared<ObjectLibrary>("local");
registry->AddLibrary(library);
library->Register<Env>(
library->AddFactory<Env>(
"test-local",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*guard */,
std::string* /* errmsg */) { return Env::Default(); });
ObjectLibrary::Default()->Register<Env>(
ObjectLibrary::Default()->AddFactory<Env>(
"test-global",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*guard */,
std::string* /* errmsg */) { return Env::Default(); });
@ -103,17 +104,17 @@ TEST_F(ObjRegistryTest, CheckShared) {
std::shared_ptr<ObjectLibrary> library =
std::make_shared<ObjectLibrary>("shared");
registry->AddLibrary(library);
library->Register<Env>(
library->AddFactory<Env>(
"unguarded",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*guard */,
std::string* /* errmsg */) { return Env::Default(); });
library->Register<Env>("guarded",
[](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
library->AddFactory<Env>(
"guarded", [](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
ASSERT_OK(registry->NewSharedObject<Env>("guarded", &shared));
ASSERT_NE(shared, nullptr);
@ -128,17 +129,17 @@ TEST_F(ObjRegistryTest, CheckStatic) {
std::shared_ptr<ObjectLibrary> library =
std::make_shared<ObjectLibrary>("static");
registry->AddLibrary(library);
library->Register<Env>(
library->AddFactory<Env>(
"unguarded",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*guard */,
std::string* /* errmsg */) { return Env::Default(); });
library->Register<Env>("guarded",
[](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
library->AddFactory<Env>(
"guarded", [](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
ASSERT_NOK(registry->NewStaticObject<Env>("guarded", &env));
ASSERT_EQ(env, nullptr);
@ -153,17 +154,17 @@ TEST_F(ObjRegistryTest, CheckUnique) {
std::shared_ptr<ObjectLibrary> library =
std::make_shared<ObjectLibrary>("unique");
registry->AddLibrary(library);
library->Register<Env>(
library->AddFactory<Env>(
"unguarded",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*guard */,
std::string* /* errmsg */) { return Env::Default(); });
library->Register<Env>("guarded",
[](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
library->AddFactory<Env>(
"guarded", [](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
ASSERT_OK(registry->NewUniqueObject<Env>("guarded", &unique));
ASSERT_NE(unique, nullptr);
@ -180,19 +181,19 @@ TEST_F(ObjRegistryTest, TestRegistryParents) {
auto cousin = ObjectRegistry::NewInstance(uncle);
auto library = parent->AddLibrary("parent");
library->Register<Env>("parent",
[](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
library->AddFactory<Env>(
"parent", [](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
library = cousin->AddLibrary("cousin");
library->Register<Env>("cousin",
[](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
library->AddFactory<Env>(
"cousin", [](const std::string& uri, std::unique_ptr<Env>* guard,
std::string* /* errmsg */) {
guard->reset(new WrappedEnv(Env::Default(), uri));
return guard->get();
});
std::unique_ptr<Env> guard;
std::string msg;
@ -409,7 +410,7 @@ TEST_F(ObjRegistryTest, TestManagedObjectsWithParent) {
TEST_F(ObjRegistryTest, TestGetOrCreateManagedObject) {
auto registry = ObjectRegistry::NewInstance();
registry->AddLibrary("test")->Register<MyCustomizable>(
registry->AddLibrary("test")->AddFactory<MyCustomizable>(
ObjectLibrary::PatternEntry::AsIndividualId("MC"),
[](const std::string& uri, std::unique_ptr<MyCustomizable>* guard,
std::string* /* errmsg */) {
@ -442,6 +443,32 @@ TEST_F(ObjRegistryTest, TestGetOrCreateManagedObject) {
ASSERT_EQ(2, obj.use_count());
}
TEST_F(ObjRegistryTest, TestDeprecatedRegex) {
Regex regex;
Env* env = nullptr;
auto registry = ObjectRegistry::NewInstance();
if (Regex::Parse("XYZ", &regex).ok()) {
registry->AddLibrary("XYZ")->Register<Env>(
"XYZ",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*env_guard*/,
std::string* /* errmsg */) { return Env::Default(); });
ASSERT_NOK(registry->NewStaticObject<Env>("X", &env));
ASSERT_OK(registry->NewStaticObject<Env>("XYZ", &env));
ASSERT_EQ(env, Env::Default());
}
if (Regex::Parse("ABC://.*", &regex).ok()) {
registry->AddLibrary("ABC")->Register<Env>(
"ABC://.*",
[](const std::string& /*uri*/, std::unique_ptr<Env>* /*env_guard*/,
std::string* /* errmsg */) { return Env::Default(); });
ASSERT_NOK(registry->NewStaticObject<Env>("ABC", &env));
ASSERT_OK(registry->NewStaticObject<Env>("ABC://123", &env));
ASSERT_EQ(env, Env::Default());
ASSERT_OK(registry->NewStaticObject<Env>("ABC://", &env));
ASSERT_EQ(env, Env::Default());
}
}
class PatternEntryTest : public testing::Test {};
TEST_F(PatternEntryTest, TestSimpleEntry) {
@ -485,6 +512,38 @@ TEST_F(PatternEntryTest, TestPatternEntry) {
ASSERT_TRUE(entry.Matches("A:BB"));
}
TEST_F(PatternEntryTest, MatchZeroOrMore) {
// Matches A:*
ObjectLibrary::PatternEntry entry("A", false);
entry.AddSeparator(":", false);
ASSERT_FALSE(entry.Matches("A"));
ASSERT_FALSE(entry.Matches("AA"));
ASSERT_FALSE(entry.Matches("AB"));
ASSERT_FALSE(entry.Matches("B"));
ASSERT_TRUE(entry.Matches("A:"));
ASSERT_FALSE(entry.Matches("B:"));
ASSERT_FALSE(entry.Matches("B:A"));
ASSERT_FALSE(entry.Matches("AA:"));
ASSERT_FALSE(entry.Matches("AA:B"));
ASSERT_FALSE(entry.Matches("AA:BB"));
ASSERT_TRUE(entry.Matches("A:B"));
ASSERT_TRUE(entry.Matches("A:BB"));
entry.SetOptional(true); // Now matches "A" or "A:*"
ASSERT_TRUE(entry.Matches("A"));
ASSERT_FALSE(entry.Matches("AA"));
ASSERT_FALSE(entry.Matches("AB"));
ASSERT_FALSE(entry.Matches("B"));
ASSERT_TRUE(entry.Matches("A:"));
ASSERT_FALSE(entry.Matches("B:"));
ASSERT_FALSE(entry.Matches("B:A"));
ASSERT_FALSE(entry.Matches("AA:"));
ASSERT_FALSE(entry.Matches("AA:B"));
ASSERT_FALSE(entry.Matches("AA:BB"));
ASSERT_TRUE(entry.Matches("A:B"));
ASSERT_TRUE(entry.Matches("A:BB"));
}
TEST_F(PatternEntryTest, TestSuffixEntry) {
ObjectLibrary::PatternEntry entry("AA", true);
entry.AddSuffix("BB");

View File

@ -194,7 +194,7 @@ NewCompactOnDeletionCollectorFactory(size_t sliding_window_size,
namespace {
static int RegisterTablePropertiesCollectorFactories(
ObjectLibrary& library, const std::string& /*arg*/) {
library.Register<TablePropertiesCollectorFactory>(
library.AddFactory<TablePropertiesCollectorFactory>(
CompactOnDeletionCollectorFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<TablePropertiesCollectorFactory>* guard,

View File

@ -280,14 +280,14 @@ Status TtlCompactionFilterFactory::ValidateOptions(
}
int RegisterTtlObjects(ObjectLibrary& library, const std::string& /*arg*/) {
library.Register<MergeOperator>(
library.AddFactory<MergeOperator>(
TtlMergeOperator::kClassName(),
[](const std::string& /*uri*/, std::unique_ptr<MergeOperator>* guard,
std::string* /* errmsg */) {
guard->reset(new TtlMergeOperator(nullptr, nullptr));
return guard->get();
});
library.Register<CompactionFilterFactory>(
library.AddFactory<CompactionFilterFactory>(
TtlCompactionFilterFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<CompactionFilterFactory>* guard,
@ -295,7 +295,7 @@ int RegisterTtlObjects(ObjectLibrary& library, const std::string& /*arg*/) {
guard->reset(new TtlCompactionFilterFactory(0, nullptr, nullptr));
return guard->get();
});
library.Register<CompactionFilter>(
library.AddFactory<CompactionFilter>(
TtlCompactionFilter::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<CompactionFilter>* /*guard*/,

View File

@ -751,14 +751,14 @@ class DummyFilterFactory : public CompactionFilterFactory {
static int RegisterTestObjects(ObjectLibrary& library,
const std::string& /*arg*/) {
library.Register<CompactionFilter>(
library.AddFactory<CompactionFilter>(
"DummyFilter", [](const std::string& /*uri*/,
std::unique_ptr<CompactionFilter>* /*guard*/,
std::string* /* errmsg */) {
static DummyFilter dummy;
return &dummy;
});
library.Register<CompactionFilterFactory>(
library.AddFactory<CompactionFilterFactory>(
"DummyFilterFactory", [](const std::string& /*uri*/,
std::unique_ptr<CompactionFilterFactory>* guard,
std::string* /* errmsg */) {