diff --git a/HISTORY.md b/HISTORY.md index ef98974ff5..da10936125 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -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()`. diff --git a/db/compaction/sst_partitioner.cc b/db/compaction/sst_partitioner.cc index 36dcf80c5d..9e7f9fa892 100644 --- a/db/compaction/sst_partitioner.cc +++ b/db/compaction/sst_partitioner.cc @@ -62,7 +62,7 @@ std::shared_ptr NewSstPartitionerFixedPrefixFactory( namespace { static int RegisterSstPartitionerFactories(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( SstPartitionerFixedPrefixFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, diff --git a/env/env.cc b/env/env.cc index 8555034d13..186429c157 100644 --- a/env/env.cc +++ b/env/env.cc @@ -33,13 +33,13 @@ namespace { #ifndef ROCKSDB_LITE static int RegisterBuiltinEnvs(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register(MockEnv::kClassName(), [](const std::string& /*uri*/, - std::unique_ptr* guard, - std::string* /* errmsg */) { + library.AddFactory(MockEnv::kClassName(), [](const std::string& /*uri*/, + std::unique_ptr* guard, + std::string* /* errmsg */) { guard->reset(MockEnv::Create(Env::Default())); return guard->get(); }); - library.Register( + library.AddFactory( CompositeEnvWrapper::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* 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( + library.AddFactory( EmulatedSystemClock::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { diff --git a/env/env_encryption.cc b/env/env_encryption.cc index 4a2b68bc75..5c440a2081 100644 --- a/env/env_encryption.cc +++ b/env/env_encryption.cc @@ -1275,7 +1275,7 @@ static void RegisterEncryptionBuiltins() { std::call_once(once, [&]() { auto lib = ObjectRegistry::Default()->AddLibrary("encryption"); // Match "CTR" or "CTR://test" - lib->Register( + lib->AddFactory( ObjectLibrary::PatternEntry(CTREncryptionProvider::kClassName(), true) .AddSuffix("://test"), [](const std::string& uri, std::unique_ptr* guard, @@ -1290,7 +1290,7 @@ static void RegisterEncryptionBuiltins() { return guard->get(); }); - lib->Register( + lib->AddFactory( "1://test", [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -1301,7 +1301,7 @@ static void RegisterEncryptionBuiltins() { }); // Match "ROT13" or "ROT13:[0-9]+" - lib->Register( + lib->AddFactory( ObjectLibrary::PatternEntry(ROT13BlockCipher::kClassName(), true) .AddNumber(":"), [](const std::string& uri, std::unique_ptr* guard, diff --git a/env/env_test.cc b/env/env_test.cc index c9488c950b..287b4f4426 100644 --- a/env/env_test.cc +++ b/env/env_test.cc @@ -2492,7 +2492,7 @@ TEST_F(CreateEnvTest, CreateDefaultSystemClock) { TEST_F(CreateEnvTest, CreateMockSystemClock) { std::shared_ptr mock, copy; - config_options_.registry->AddLibrary("test")->Register( + config_options_.registry->AddLibrary("test")->AddFactory( MockSystemClock::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* 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(WrappedEnv::kClassName(), [](const std::string& /*uri*/, - std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new WrappedEnv(nullptr)); - return guard->get(); - }); + lib.AddFactory( + WrappedEnv::kClassName(), + [](const std::string& /*uri*/, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new WrappedEnv(nullptr)); + return guard->get(); + }); } }; } // namespace diff --git a/env/file_system.cc b/env/file_system.cc index 5a2c75cb25..618b6915df 100644 --- a/env/file_system.cc +++ b/env/file_system.cc @@ -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( + library.AddFactory( TimedFileSystem::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new TimedFileSystem(nullptr)); return guard->get(); }); - library.Register( + library.AddFactory( ReadOnlyFileSystem::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new ReadOnlyFileSystem(nullptr)); return guard->get(); }); - library.Register( + library.AddFactory( EncryptedFileSystem::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* errmsg) { @@ -56,7 +56,7 @@ static int RegisterBuiltinFileSystems(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( MockFileSystem::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -64,7 +64,7 @@ static int RegisterBuiltinFileSystems(ObjectLibrary& library, return guard->get(); }); #ifndef OS_WIN - library.Register( + library.AddFactory( ChrootFileSystem::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { diff --git a/env/fs_posix.cc b/env/fs_posix.cc index 52264ce7c2..a6b6bbd6b9 100644 --- a/env/fs_posix.cc +++ b/env/fs_posix.cc @@ -1124,8 +1124,8 @@ std::shared_ptr FileSystem::Default() { #ifndef ROCKSDB_LITE static FactoryFunc posix_filesystem_reg = - ObjectLibrary::Default()->Register( - "posix://.*", + ObjectLibrary::Default()->AddFactory( + ObjectLibrary::PatternEntry("posix").AddSeparator("://", false), [](const std::string& /* uri */, std::unique_ptr* f, std::string* /* errmsg */) { f->reset(new PosixFileSystem()); diff --git a/include/rocksdb/utilities/object_registry.h b/include/rocksdb/utilities/object_registry.h index bc7d7ce3f2..a5c4b36c50 100644 --- a/include/rocksdb/utilities/object_registry.h +++ b/include/rocksdb/utilities/object_registry.h @@ -16,6 +16,7 @@ #include #include "rocksdb/status.h" +#include "rocksdb/utilities/regex.h" namespace ROCKSDB_NAMESPACE { class Customizable; @@ -41,17 +42,48 @@ template using ConfigureFunc = std::function; 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, ®ex_).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 class FactoryEntry : public Entry { public: - FactoryEntry(const PatternEntry& e, FactoryFunc f) + FactoryEntry(Entry* e, FactoryFunc 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* guard, @@ -171,7 +206,7 @@ class ObjectLibrary { const FactoryFunc& GetFactory() const { return factory_; } private: - PatternEntry entry_; // The pattern for this entry + std::unique_ptr entry_; // What to match for this entry FactoryFunc 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 - FactoryFunc FindFactory(const std::string& pattern) const { + FactoryFunc FindFactory(const std::string& target) const { std::unique_lock 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*>(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 const FactoryFunc& Register(const std::string& pattern, const FactoryFunc& factory) { - PatternEntry entry(pattern); - return Register(entry, factory); + std::unique_ptr entry( + new FactoryEntry(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 - const FactoryFunc& Register(const PatternEntry& pattern, - const FactoryFunc& func) { - std::unique_ptr entry(new FactoryEntry(pattern, func)); - std::unique_lock lock(mu_); - auto& factories = factories_[T::Type()]; - factories.emplace_back(std::move(entry)); + const FactoryFunc& AddFactory(const std::string& name, + const FactoryFunc& func) { + std::unique_ptr entry( + new FactoryEntry(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 + const FactoryFunc& AddFactory(const PatternEntry& entry, + const FactoryFunc& func) { + std::unique_ptr factory( + new FactoryEntry(new PatternEntry(entry), func)); + AddFactoryEntry(T::Type(), std::move(factory)); return func; } @@ -230,6 +290,12 @@ class ObjectLibrary { static std::shared_ptr& Default(); private: + void AddFactoryEntry(const char* type, std::unique_ptr&& entry) { + std::unique_lock 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 T* NewObject(const std::string& target, std::unique_ptr* guard, std::string* errmsg) { @@ -491,7 +556,7 @@ class ObjectRegistry { const std::shared_ptr& 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 const FactoryFunc FindFactory(const std::string& name) const { diff --git a/memory/memory_allocator.cc b/memory/memory_allocator.cc index 4726e5e856..34dce9bb66 100644 --- a/memory/memory_allocator.cc +++ b/memory/memory_allocator.cc @@ -24,14 +24,14 @@ static std::unordered_map ma_wrapper_type_info = { #ifndef ROCKSDB_LITE static int RegisterBuiltinAllocators(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( DefaultMemoryAllocator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /*errmsg*/) { guard->reset(new DefaultMemoryAllocator()); return guard->get(); }); - library.Register( + library.AddFactory( CountedMemoryAllocator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -39,7 +39,7 @@ static int RegisterBuiltinAllocators(ObjectLibrary& library, std::make_shared())); return guard->get(); }); - library.Register( + library.AddFactory( JemallocNodumpAllocator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* errmsg) { @@ -49,7 +49,7 @@ static int RegisterBuiltinAllocators(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( MemkindKmemAllocator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* errmsg) { diff --git a/monitoring/statistics.cc b/monitoring/statistics.cc index eb5941ba50..c7c076cc60 100644 --- a/monitoring/statistics.cc +++ b/monitoring/statistics.cc @@ -288,7 +288,7 @@ std::shared_ptr CreateDBStatistics() { #ifndef ROCKSDB_LITE static int RegisterBuiltinStatistics(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( StatisticsImpl::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { diff --git a/options/customizable_test.cc b/options/customizable_test.cc index 2973f3c623..c61a512434 100644 --- a/options/customizable_test.cc +++ b/options/customizable_test.cc @@ -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( + library.AddFactory( ObjectLibrary::PatternEntry("A", true).AddSeparator("_"), [](const std::string& name, std::unique_ptr* guard, std::string* /* msg */) { @@ -189,7 +189,7 @@ static int RegisterCustomTestObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( "S", [](const std::string& name, std::unique_ptr* /* 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( + ObjectLibrary::Default()->AddFactory( ObjectLibrary::PatternEntry("TEST", false).AddSeparator("_"), [](const std::string& name, std::unique_ptr* guard, std::string* /* msg */) { @@ -565,7 +565,7 @@ TEST_F(CustomizableTest, PrepareOptionsTest) { } }; - ObjectLibrary::Default()->Register( + ObjectLibrary::Default()->AddFactory( "P", [](const std::string& /*name*/, std::unique_ptr* guard, std::string* /* msg */) { @@ -1029,7 +1029,7 @@ TEST_F(CustomizableTest, FactoryFunctionTest) { TEST_F(CustomizableTest, URLFactoryTest) { std::unique_ptr unique; - config_options_.registry->AddLibrary("URL")->Register( + config_options_.registry->AddLibrary("URL")->AddFactory( ObjectLibrary::PatternEntry("Z", false).AddSeparator(""), [](const std::string& name, std::unique_ptr* guard, std::string* /* msg */) { @@ -1186,7 +1186,7 @@ TEST_F(CustomizableTest, CreateManagedObjects) { }; config_options_.registry->AddLibrary("Managed") - ->Register( + ->AddFactory( 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( + library.AddFactory( mock::MockTableFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new mock::MockTableFactory()); return guard->get(); }); - library.Register( + library.AddFactory( OnFileDeletionListener::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new OnFileDeletionListener()); return guard->get(); }); - library.Register( + library.AddFactory( FlushCounterListener::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { @@ -1467,7 +1467,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); // Load any locally defined objects here - library.Register( + library.AddFactory( MockSliceTransform::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -1475,7 +1475,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, guard->reset(new MockSliceTransform()); return guard->get(); }); - library.Register( + library.AddFactory( TestStatistics::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { @@ -1483,7 +1483,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(MockEncryptionProvider::kClassName(), true) .AddSuffix("://test"), [](const std::string& uri, std::unique_ptr* guard, @@ -1491,20 +1491,21 @@ static int RegisterLocalObjects(ObjectLibrary& library, guard->reset(new MockEncryptionProvider(uri)); return guard->get(); }); - library.Register("Mock", [](const std::string& /*uri*/, - std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new MockCipher()); - return guard->get(); - }); - library.Register( + library.AddFactory( + "Mock", + [](const std::string& /*uri*/, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new MockCipher()); + return guard->get(); + }); + library.AddFactory( MockMemoryAllocator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new MockMemoryAllocator()); return guard->get(); }); - library.Register( + library.AddFactory( TestFlushBlockPolicyFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -1513,7 +1514,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( TestSecondaryCache::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { @@ -1521,7 +1522,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( DummyFileSystem::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { @@ -1529,7 +1530,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( MockSstPartitionerFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -1538,7 +1539,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( MockFileChecksumGenFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -1547,7 +1548,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( MockTablePropertiesCollectorFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -1556,7 +1557,7 @@ static int RegisterLocalObjects(ObjectLibrary& library, return guard->get(); }); - library.Register( + library.AddFactory( MockRateLimiter::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { diff --git a/options/options_test.cc b/options/options_test.cc index a78d64ef77..31a253bfd2 100644 --- a/options/options_test.cc +++ b/options/options_test.cc @@ -388,7 +388,7 @@ TEST_F(OptionsTest, GetColumnFamilyOptionsFromStringTest) { // Comparator from object registry std::string kCompName = "reverse_comp"; - ObjectLibrary::Default()->Register( + ObjectLibrary::Default()->AddFactory( kCompName, [](const std::string& /*name*/, std::unique_ptr* /*guard*/, @@ -1291,7 +1291,7 @@ TEST_F(OptionsTest, GetOptionsFromStringTest) { NewBlockBasedTableFactory(block_based_table_options)); // Register an Env with object registry. - ObjectLibrary::Default()->Register( + ObjectLibrary::Default()->AddFactory( CustomEnv::kClassName(), [](const std::string& /*name*/, std::unique_ptr* /*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( + ->AddFactory( 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( + library.AddFactory( "Test" + arg, [](const std::string& name, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new TestEventListener(name.substr(4))); return guard->get(); }); - library.Register( + library.AddFactory( "TestConfig" + arg, [](const std::string& name, std::unique_ptr* 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( + library.AddFactory( arg, [](const std::string& /*name*/, std::unique_ptr* /*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( + ObjectLibrary::Default()->AddFactory( kCompName, [](const std::string& /*name*/, std::unique_ptr* /*guard*/, @@ -2968,7 +2968,7 @@ TEST_F(OptionsOldApiTest, GetOptionsFromStringTest) { NewBlockBasedTableFactory(block_based_table_options)); // Register an Env with object registry. - ObjectLibrary::Default()->Register( + ObjectLibrary::Default()->AddFactory( "CustomEnvDefault", [](const std::string& /*name*/, std::unique_ptr* /*env_guard*/, std::string* /* errmsg */) { diff --git a/table/block_based/flush_block_policy.cc b/table/block_based/flush_block_policy.cc index 13332accb1..f5fbe76fd4 100644 --- a/table/block_based/flush_block_policy.cc +++ b/table/block_based/flush_block_policy.cc @@ -94,7 +94,7 @@ FlushBlockPolicy* FlushBlockBySizePolicyFactory::NewFlushBlockPolicy( #ifndef ROCKSDB_LITE static int RegisterFlushBlockPolicyFactories(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( FlushBlockBySizePolicyFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -102,7 +102,7 @@ static int RegisterFlushBlockPolicyFactories(ObjectLibrary& library, guard->reset(new FlushBlockBySizePolicyFactory()); return guard->get(); }); - library.Register( + library.AddFactory( FlushBlockEveryKeyPolicyFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, diff --git a/table/plain/plain_table_factory.cc b/table/plain/plain_table_factory.cc index a6cf42f1e3..3db484b053 100644 --- a/table/plain/plain_table_factory.cc +++ b/table/plain/plain_table_factory.cc @@ -167,7 +167,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library, pattern.AddNumber(":"); return pattern; }; - library.Register( + library.AddFactory( AsPattern(VectorRepFactory::kClassName(), VectorRepFactory::kNickName()), [](const std::string& uri, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -180,7 +180,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( AsPattern(SkipListFactory::kClassName(), SkipListFactory::kNickName()), [](const std::string& uri, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -193,7 +193,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( AsPattern("HashLinkListRepFactory", "hash_linkedlist"), [](const std::string& uri, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -207,7 +207,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( AsPattern("HashSkipListRepFactory", "prefix_hash"), [](const std::string& uri, std::unique_ptr* guard, std::string* /*errmsg*/) { @@ -221,7 +221,7 @@ static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( "cuckoo", [](const std::string& /*uri*/, std::unique_ptr* /*guard*/, std::string* errmsg) { diff --git a/table/table_factory.cc b/table/table_factory.cc index 0fbb57cf5e..fc5c5ccde4 100644 --- a/table/table_factory.cc +++ b/table/table_factory.cc @@ -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( + library->AddFactory( TableFactory::kBlockBasedTableName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new BlockBasedTableFactory()); return guard->get(); }); - library->Register( + library->AddFactory( TableFactory::kPlainTableName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new PlainTableFactory()); return guard->get(); }); - library->Register( + library->AddFactory( TableFactory::kCuckooTableName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { diff --git a/test_util/testutil.cc b/test_util/testutil.cc index 07d0ef2520..1fb74ab3c3 100644 --- a/test_util/testutil.cc +++ b/test_util/testutil.cc @@ -678,7 +678,7 @@ class SpecialSkipListFactory : public MemTableRepFactory { public: #ifndef ROCKSDB_LITE static bool Register(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(SpecialSkipListFactory::kClassName(), true) .AddNumber(":"), [](const std::string& uri, std::unique_ptr* 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( + library.AddFactory( test::SimpleSuffixReverseComparator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* /*guard*/, @@ -747,27 +747,27 @@ int RegisterTestObjects(ObjectLibrary& library, const std::string& arg) { return &ssrc; }); SpecialSkipListFactory::Register(library, arg); - library.Register( + library.AddFactory( "Changling", [](const std::string& uri, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new test::ChanglingMergeOperator(uri)); return guard->get(); }); - library.Register( + library.AddFactory( "Changling", [](const std::string& uri, std::unique_ptr* /*guard*/, std::string* /* errmsg */) { return new test::ChanglingCompactionFilter(uri); }); - library.Register( + library.AddFactory( "Changling", [](const std::string& uri, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new test::ChanglingCompactionFilterFactory(uri)); return guard->get(); }); - library.Register( + library.AddFactory( MockSystemClock::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { diff --git a/util/comparator.cc b/util/comparator.cc index 0cdce3a361..6796fdfef3 100644 --- a/util/comparator.cc +++ b/util/comparator.cc @@ -231,12 +231,12 @@ const Comparator* ReverseBytewiseComparator() { #ifndef ROCKSDB_LITE static int RegisterBuiltinComparators(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( BytewiseComparatorImpl::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return BytewiseComparator(); }); - library.Register( + library.AddFactory( ReverseBytewiseComparatorImpl::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* /*guard */, diff --git a/util/file_checksum_helper.cc b/util/file_checksum_helper.cc index 2fcbf1e9ef..a739203524 100644 --- a/util/file_checksum_helper.cc +++ b/util/file_checksum_helper.cc @@ -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( + library.AddFactory( FileChecksumGenCrc32cFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, diff --git a/util/rate_limiter.cc b/util/rate_limiter.cc index ef9f1ca943..72d9319673 100644 --- a/util/rate_limiter.cc +++ b/util/rate_limiter.cc @@ -431,7 +431,7 @@ namespace { #ifndef ROCKSDB_LITE static int RegisterBuiltinRateLimiters(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( GenericRateLimiter::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /*errmsg*/) { diff --git a/util/slice.cc b/util/slice.cc index 268eb1b4ed..509b0e8854 100644 --- a/util/slice.cc +++ b/util/slice.cc @@ -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( + library.AddFactory( NoopTransform::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -154,7 +154,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library, guard->reset(NewNoopTransform()); return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(FixedPrefixTransform::kNickName(), false) .AddNumber(":"), [](const std::string& uri, std::unique_ptr* guard, @@ -164,7 +164,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library, guard->reset(NewFixedPrefixTransform(len)); return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(FixedPrefixTransform::kClassName(), true) .AddNumber("."), [](const std::string& uri, std::unique_ptr* guard, @@ -178,7 +178,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library, } return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(CappedPrefixTransform::kNickName(), false) .AddNumber(":"), [](const std::string& uri, std::unique_ptr* guard, @@ -188,7 +188,7 @@ static int RegisterBuiltinSliceTransform(ObjectLibrary& library, guard->reset(NewCappedPrefixTransform(len)); return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(CappedPrefixTransform::kClassName(), true) .AddNumber("."), [](const std::string& uri, std::unique_ptr* guard, diff --git a/utilities/cassandra/cassandra_compaction_filter.cc b/utilities/cassandra/cassandra_compaction_filter.cc index 3d49ea0ab7..d59db47d41 100644 --- a/utilities/cassandra/cassandra_compaction_filter.cc +++ b/utilities/cassandra/cassandra_compaction_filter.cc @@ -80,21 +80,21 @@ CassandraCompactionFilterFactory::CreateCompactionFilter( #ifndef ROCKSDB_LITE int RegisterCassandraObjects(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( CassandraValueMergeOperator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new CassandraValueMergeOperator(0)); return guard->get(); }); - library.Register( + library.AddFactory( CassandraCompactionFilter::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return new CassandraCompactionFilter(false, 0); }); - library.Register( + library.AddFactory( CassandraCompactionFilterFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, diff --git a/utilities/compaction_filters.cc b/utilities/compaction_filters.cc index d527ee5b8b..8763901c3d 100644 --- a/utilities/compaction_filters.cc +++ b/utilities/compaction_filters.cc @@ -16,7 +16,7 @@ namespace ROCKSDB_NAMESPACE { #ifndef ROCKSDB_LITE static int RegisterBuiltinCompactionFilters(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( RemoveEmptyValueCompactionFilter::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* /*guard*/, diff --git a/utilities/merge_operators.cc b/utilities/merge_operators.cc index 180e577db7..c97e9ce251 100644 --- a/utilities/merge_operators.cc +++ b/utilities/merge_operators.cc @@ -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( + library.AddFactory( ObjectLibrary::PatternEntry(StringAppendOperator::kClassName()) .AnotherName(StringAppendOperator::kNickName()), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -63,7 +63,7 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library, guard->reset(new StringAppendOperator(",")); return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(StringAppendTESTOperator::kClassName()) .AnotherName(StringAppendTESTOperator::kNickName()), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -71,7 +71,7 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library, guard->reset(new StringAppendTESTOperator(",")); return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(SortList::kClassName()) .AnotherName(SortList::kNickName()), [](const std::string& /*uri*/, std::unique_ptr* guard, @@ -79,7 +79,7 @@ static int RegisterBuiltinMergeOperators(ObjectLibrary& library, guard->reset(new SortList()); return guard->get(); }); - library.Register( + library.AddFactory( ObjectLibrary::PatternEntry(BytesXOROperator::kClassName()) .AnotherName(BytesXOROperator::kNickName()), [](const std::string& /*uri*/, std::unique_ptr* guard, diff --git a/utilities/object_registry.cc b/utilities/object_registry.cc index e41d3172d2..7b0a6bb5a8 100644 --- a/utilities/object_registry.cc +++ b/utilities/object_registry.cc @@ -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) { diff --git a/utilities/object_registry_test.cc b/utilities/object_registry_test.cc index 55bdc14fd5..77bf2ec1c3 100644 --- a/utilities/object_registry_test.cc +++ b/utilities/object_registry_test.cc @@ -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 test_reg_a = ObjectLibrary::Default()->Register( +static FactoryFunc test_reg_a = ObjectLibrary::Default()->AddFactory( ObjectLibrary::PatternEntry("a", false).AddSeparator("://"), [](const std::string& /*uri*/, std::unique_ptr* /*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 test_reg_b = ObjectLibrary::Default()->Register( +static FactoryFunc test_reg_b = ObjectLibrary::Default()->AddFactory( ObjectLibrary::PatternEntry("b", false).AddSeparator("://"), [](const std::string& uri, std::unique_ptr* env_guard, std::string* /* errmsg */) { @@ -77,12 +78,12 @@ TEST_F(ObjRegistryTest, LocalRegistry) { std::shared_ptr library = std::make_shared("local"); registry->AddLibrary(library); - library->Register( + library->AddFactory( "test-local", [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return Env::Default(); }); - ObjectLibrary::Default()->Register( + ObjectLibrary::Default()->AddFactory( "test-global", [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return Env::Default(); }); @@ -103,17 +104,17 @@ TEST_F(ObjRegistryTest, CheckShared) { std::shared_ptr library = std::make_shared("shared"); registry->AddLibrary(library); - library->Register( + library->AddFactory( "unguarded", [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return Env::Default(); }); - library->Register("guarded", - [](const std::string& uri, std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new WrappedEnv(Env::Default(), uri)); - return guard->get(); - }); + library->AddFactory( + "guarded", [](const std::string& uri, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new WrappedEnv(Env::Default(), uri)); + return guard->get(); + }); ASSERT_OK(registry->NewSharedObject("guarded", &shared)); ASSERT_NE(shared, nullptr); @@ -128,17 +129,17 @@ TEST_F(ObjRegistryTest, CheckStatic) { std::shared_ptr library = std::make_shared("static"); registry->AddLibrary(library); - library->Register( + library->AddFactory( "unguarded", [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return Env::Default(); }); - library->Register("guarded", - [](const std::string& uri, std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new WrappedEnv(Env::Default(), uri)); - return guard->get(); - }); + library->AddFactory( + "guarded", [](const std::string& uri, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new WrappedEnv(Env::Default(), uri)); + return guard->get(); + }); ASSERT_NOK(registry->NewStaticObject("guarded", &env)); ASSERT_EQ(env, nullptr); @@ -153,17 +154,17 @@ TEST_F(ObjRegistryTest, CheckUnique) { std::shared_ptr library = std::make_shared("unique"); registry->AddLibrary(library); - library->Register( + library->AddFactory( "unguarded", [](const std::string& /*uri*/, std::unique_ptr* /*guard */, std::string* /* errmsg */) { return Env::Default(); }); - library->Register("guarded", - [](const std::string& uri, std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new WrappedEnv(Env::Default(), uri)); - return guard->get(); - }); + library->AddFactory( + "guarded", [](const std::string& uri, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new WrappedEnv(Env::Default(), uri)); + return guard->get(); + }); ASSERT_OK(registry->NewUniqueObject("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("parent", - [](const std::string& uri, std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new WrappedEnv(Env::Default(), uri)); - return guard->get(); - }); + library->AddFactory( + "parent", [](const std::string& uri, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new WrappedEnv(Env::Default(), uri)); + return guard->get(); + }); library = cousin->AddLibrary("cousin"); - library->Register("cousin", - [](const std::string& uri, std::unique_ptr* guard, - std::string* /* errmsg */) { - guard->reset(new WrappedEnv(Env::Default(), uri)); - return guard->get(); - }); + library->AddFactory( + "cousin", [](const std::string& uri, std::unique_ptr* guard, + std::string* /* errmsg */) { + guard->reset(new WrappedEnv(Env::Default(), uri)); + return guard->get(); + }); std::unique_ptr guard; std::string msg; @@ -409,7 +410,7 @@ TEST_F(ObjRegistryTest, TestManagedObjectsWithParent) { TEST_F(ObjRegistryTest, TestGetOrCreateManagedObject) { auto registry = ObjectRegistry::NewInstance(); - registry->AddLibrary("test")->Register( + registry->AddLibrary("test")->AddFactory( ObjectLibrary::PatternEntry::AsIndividualId("MC"), [](const std::string& uri, std::unique_ptr* 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", ®ex).ok()) { + registry->AddLibrary("XYZ")->Register( + "XYZ", + [](const std::string& /*uri*/, std::unique_ptr* /*env_guard*/, + std::string* /* errmsg */) { return Env::Default(); }); + ASSERT_NOK(registry->NewStaticObject("X", &env)); + ASSERT_OK(registry->NewStaticObject("XYZ", &env)); + ASSERT_EQ(env, Env::Default()); + } + if (Regex::Parse("ABC://.*", ®ex).ok()) { + registry->AddLibrary("ABC")->Register( + "ABC://.*", + [](const std::string& /*uri*/, std::unique_ptr* /*env_guard*/, + std::string* /* errmsg */) { return Env::Default(); }); + ASSERT_NOK(registry->NewStaticObject("ABC", &env)); + ASSERT_OK(registry->NewStaticObject("ABC://123", &env)); + ASSERT_EQ(env, Env::Default()); + ASSERT_OK(registry->NewStaticObject("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"); diff --git a/utilities/table_properties_collectors/compact_on_deletion_collector.cc b/utilities/table_properties_collectors/compact_on_deletion_collector.cc index a05ef795db..0c0d0751fe 100644 --- a/utilities/table_properties_collectors/compact_on_deletion_collector.cc +++ b/utilities/table_properties_collectors/compact_on_deletion_collector.cc @@ -194,7 +194,7 @@ NewCompactOnDeletionCollectorFactory(size_t sliding_window_size, namespace { static int RegisterTablePropertiesCollectorFactories( ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( CompactOnDeletionCollectorFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, diff --git a/utilities/ttl/db_ttl_impl.cc b/utilities/ttl/db_ttl_impl.cc index df6d50b239..96b6081e15 100644 --- a/utilities/ttl/db_ttl_impl.cc +++ b/utilities/ttl/db_ttl_impl.cc @@ -280,14 +280,14 @@ Status TtlCompactionFilterFactory::ValidateOptions( } int RegisterTtlObjects(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( TtlMergeOperator::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) { guard->reset(new TtlMergeOperator(nullptr, nullptr)); return guard->get(); }); - library.Register( + library.AddFactory( TtlCompactionFilterFactory::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* 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( + library.AddFactory( TtlCompactionFilter::kClassName(), [](const std::string& /*uri*/, std::unique_ptr* /*guard*/, diff --git a/utilities/ttl/ttl_test.cc b/utilities/ttl/ttl_test.cc index e3ddd1b130..3daef74ca8 100644 --- a/utilities/ttl/ttl_test.cc +++ b/utilities/ttl/ttl_test.cc @@ -751,14 +751,14 @@ class DummyFilterFactory : public CompactionFilterFactory { static int RegisterTestObjects(ObjectLibrary& library, const std::string& /*arg*/) { - library.Register( + library.AddFactory( "DummyFilter", [](const std::string& /*uri*/, std::unique_ptr* /*guard*/, std::string* /* errmsg */) { static DummyFilter dummy; return &dummy; }); - library.Register( + library.AddFactory( "DummyFilterFactory", [](const std::string& /*uri*/, std::unique_ptr* guard, std::string* /* errmsg */) {