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
main
mrambacher 2 years ago committed by Facebook GitHub Bot
parent 6bab278291
commit 1973fcba11
  1. 1
      HISTORY.md
  2. 2
      db/compaction/sst_partitioner.cc
  3. 10
      env/env.cc
  4. 6
      env/env_encryption.cc
  5. 15
      env/env_test.cc
  6. 10
      env/file_system.cc
  7. 4
      env/fs_posix.cc
  8. 151
      include/rocksdb/utilities/object_registry.h
  9. 8
      memory/memory_allocator.cc
  10. 2
      monitoring/statistics.cc
  11. 53
      options/customizable_test.cc
  12. 16
      options/options_test.cc
  13. 4
      table/block_based/flush_block_policy.cc
  14. 10
      table/plain/plain_table_factory.cc
  15. 6
      table/table_factory.cc
  16. 12
      test_util/testutil.cc
  17. 4
      util/comparator.cc
  18. 2
      util/file_checksum_helper.cc
  19. 2
      util/rate_limiter.cc
  20. 10
      util/slice.cc
  21. 6
      utilities/cassandra/cassandra_compaction_filter.cc
  22. 2
      utilities/compaction_filters.cc
  23. 8
      utilities/merge_operators.cc
  24. 2
      utilities/object_registry.cc
  25. 135
      utilities/object_registry_test.cc
  26. 2
      utilities/table_properties_collectors/compact_on_deletion_collector.cc
  27. 6
      utilities/ttl/db_ttl_impl.cc
  28. 4
      utilities/ttl/ttl_test.cc

@ -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 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. * 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. * 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 ### Behavior Changes
* `DB::DestroyColumnFamilyHandle()` will return Status::InvalidArgument() if called with `DB::DefaultColumnFamily()`. * `DB::DestroyColumnFamilyHandle()` will return Status::InvalidArgument() if called with `DB::DefaultColumnFamily()`.

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

10
env/env.cc vendored

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

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

15
env/env_test.cc vendored

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

10
env/file_system.cc vendored

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

4
env/fs_posix.cc vendored

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save