]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/include/rocksdb/utilities/object_registry.h
1 // Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
14 #include <unordered_map>
16 #include "rocksdb/status.h"
18 namespace ROCKSDB_NAMESPACE
{
20 // Returns a new T when called with a string. Populates the std::unique_ptr
21 // argument if granting ownership to caller.
24 std::function
<T
*(const std::string
&, std::unique_ptr
<T
>*, std::string
*)>;
28 // Base class for an Entry in the Registry.
32 Entry(const std::string
& name
) : name_(std::move(name
)) {}
34 // Checks to see if the target matches this entry
35 virtual bool matches(const std::string
& target
) const {
36 return name_
== target
;
38 const std::string
& Name() const { return name_
; }
41 const std::string name_
; // The name of the Entry
44 // An Entry containing a FactoryFunc for creating new Objects
46 class FactoryEntry
: public Entry
{
48 FactoryEntry(const std::string
& name
, FactoryFunc
<T
> f
)
49 : Entry(name
), pattern_(std::move(name
)), factory_(std::move(f
)) {}
50 ~FactoryEntry() override
{}
51 bool matches(const std::string
& target
) const override
{
52 return std::regex_match(target
, pattern_
);
54 // Creates a new T object.
55 T
* NewFactoryObject(const std::string
& target
, std::unique_ptr
<T
>* guard
,
56 std::string
* msg
) const {
57 return factory_(target
, guard
, msg
);
61 std::regex pattern_
; // The pattern for this entry
62 FactoryFunc
<T
> factory_
;
63 }; // End class FactoryEntry
65 // Finds the entry matching the input name and type
66 const Entry
* FindEntry(const std::string
& type
,
67 const std::string
& name
) const;
68 void Dump(Logger
* logger
) const;
70 // Registers the factory with the library for the pattern.
71 // If the pattern matches, the factory may be used to create a new object.
73 const FactoryFunc
<T
>& Register(const std::string
& pattern
,
74 const FactoryFunc
<T
>& factory
) {
75 std::unique_ptr
<Entry
> entry(new FactoryEntry
<T
>(pattern
, factory
));
76 AddEntry(T::Type(), entry
);
79 // Returns the default ObjectLibrary
80 static std::shared_ptr
<ObjectLibrary
>& Default();
83 // Adds the input entry to the list for the given type
84 void AddEntry(const std::string
& type
, std::unique_ptr
<Entry
>& entry
);
86 // ** FactoryFunctions for this loader, organized by type
87 std::unordered_map
<std::string
, std::vector
<std::unique_ptr
<Entry
>>> entries_
;
90 // The ObjectRegistry is used to register objects that can be created by a
91 // name/pattern at run-time where the specific implementation of the object may
92 // not be known in advance.
93 class ObjectRegistry
{
95 static std::shared_ptr
<ObjectRegistry
> NewInstance();
99 void AddLibrary(const std::shared_ptr
<ObjectLibrary
>& library
) {
100 libraries_
.emplace_back(library
);
103 // Creates a new T using the factory function that was registered with a
104 // pattern that matches the provided "target" string according to
107 // If no registered functions match, returns nullptr. If multiple functions
108 // match, the factory function used is unspecified.
110 // Populates res_guard with result pointer if caller is granted ownership.
111 template <typename T
>
112 T
* NewObject(const std::string
& target
, std::unique_ptr
<T
>* guard
,
113 std::string
* errmsg
) {
115 const auto* basic
= FindEntry(T::Type(), target
);
116 if (basic
!= nullptr) {
117 const auto* factory
=
118 static_cast<const ObjectLibrary::FactoryEntry
<T
>*>(basic
);
119 return factory
->NewFactoryObject(target
, guard
, errmsg
);
121 *errmsg
= std::string("Could not load ") + T::Type();
126 // Creates a new unique T using the input factory functions.
127 // Returns OK if a new unique T was successfully created
128 // Returns NotSupported if the type/target could not be created
129 // Returns InvalidArgument if the factory return an unguarded object
130 // (meaning it cannot be managed by a unique ptr)
131 template <typename T
>
132 Status
NewUniqueObject(const std::string
& target
,
133 std::unique_ptr
<T
>* result
) {
135 T
* ptr
= NewObject(target
, result
, &errmsg
);
136 if (ptr
== nullptr) {
137 return Status::NotSupported(errmsg
, target
);
138 } else if (*result
) {
141 return Status::InvalidArgument(std::string("Cannot make a unique ") +
142 T::Type() + " from unguarded one ",
147 // Creates a new shared T using the input factory functions.
148 // Returns OK if a new shared T was successfully created
149 // Returns NotSupported if the type/target could not be created
150 // Returns InvalidArgument if the factory return an unguarded object
151 // (meaning it cannot be managed by a shared ptr)
152 template <typename T
>
153 Status
NewSharedObject(const std::string
& target
,
154 std::shared_ptr
<T
>* result
) {
156 std::unique_ptr
<T
> guard
;
157 T
* ptr
= NewObject(target
, &guard
, &errmsg
);
158 if (ptr
== nullptr) {
159 return Status::NotSupported(errmsg
, target
);
161 result
->reset(guard
.release());
164 return Status::InvalidArgument(std::string("Cannot make a shared ") +
165 T::Type() + " from unguarded one ",
170 // Creates a new static T using the input factory functions.
171 // Returns OK if a new static T was successfully created
172 // Returns NotSupported if the type/target could not be created
173 // Returns InvalidArgument if the factory return a guarded object
174 // (meaning it is managed by a unique ptr)
175 template <typename T
>
176 Status
NewStaticObject(const std::string
& target
, T
** result
) {
178 std::unique_ptr
<T
> guard
;
179 T
* ptr
= NewObject(target
, &guard
, &errmsg
);
180 if (ptr
== nullptr) {
181 return Status::NotSupported(errmsg
, target
);
182 } else if (guard
.get()) {
183 return Status::InvalidArgument(std::string("Cannot make a static ") +
184 T::Type() + " from a guarded one ",
192 // Dump the contents of the registry to the logger
193 void Dump(Logger
* logger
) const;
196 const ObjectLibrary::Entry
* FindEntry(const std::string
& type
,
197 const std::string
& name
) const;
199 // The set of libraries to search for factories for this registry.
200 // The libraries are searched in reverse order (back to front) when
201 // searching for entries.
202 std::vector
<std::shared_ptr
<ObjectLibrary
>> libraries_
;
204 } // namespace ROCKSDB_NAMESPACE
205 #endif // ROCKSDB_LITE