1 // Copyright (c) 2011-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).
9 #include <unordered_map>
11 #include "options/configurable_helper.h"
12 #include "options/options_helper.h"
13 #include "rocksdb/convenience.h"
14 #include "rocksdb/customizable.h"
15 #include "rocksdb/status.h"
16 #include "rocksdb/utilities/object_registry.h"
18 namespace ROCKSDB_NAMESPACE
{
20 using SharedFactoryFunc
=
21 std::function
<bool(const std::string
&, std::shared_ptr
<T
>*)>;
24 using UniqueFactoryFunc
=
25 std::function
<bool(const std::string
&, std::unique_ptr
<T
>*)>;
28 using StaticFactoryFunc
= std::function
<bool(const std::string
&, T
**)>;
30 // Creates a new shared Customizable object based on the input parameters.
31 // This method parses the input value to determine the type of instance to
32 // create. If there is an existing instance (in result) and it is the same type
33 // as the object being created, the existing configuration is stored and used as
34 // the default for the new object.
36 // The value parameter specified the instance class of the object to create.
37 // If it is a simple string (e.g. BlockBasedTable), then the instance will be
38 // created using the default settings. If the value is a set of name-value
39 // pairs, then the "id" value is used to determine the instance to create and
40 // the remaining parameters are used to configure the object. Id name-value
41 // pairs are specified, there must be an "id=value" pairing or an error will
44 // The config_options parameter controls the process and how errors are
45 // returned. If ignore_unknown_options=true, unknown values are ignored during
46 // the configuration If ignore_unsupported_options=true, unknown instance types
47 // are ignored If invoke_prepare_options=true, the resulting instance wll be
48 // initialized (via PrepareOptions
50 // @param config_options Controls how the instance is created and errors are
52 // @param value Either the simple name of the instance to create, or a set of
53 // name-value pairs to
54 // create and initailzie the object
55 // @param func Optional function to call to attempt to create an instance
56 // @param result The newly created instance.
58 static Status
LoadSharedObject(const ConfigOptions
& config_options
,
59 const std::string
& value
,
60 const SharedFactoryFunc
<T
>& func
,
61 std::shared_ptr
<T
>* result
) {
63 std::unordered_map
<std::string
, std::string
> opt_map
;
64 Status status
= ConfigurableHelper::GetOptionsMap(value
, &id
, &opt_map
);
65 if (!status
.ok()) { // GetOptionsMap failed
68 std::string curr_opts
;
70 if (result
->get() != nullptr && result
->get()->GetId() == id
) {
71 // Try to get the existing options, ignoring any errors
72 ConfigOptions embedded
= config_options
;
73 embedded
.delimiter
= ";";
74 result
->get()->GetOptionString(embedded
, &curr_opts
).PermitUncheckedError();
77 if (func
== nullptr || !func(id
, result
)) { // No factory, or it failed
78 if (id
.empty() && opt_map
.empty()) {
79 // No Id and no options. Clear the object
82 } else if (id
.empty()) { // We have no Id but have options. Not good
83 return Status::NotSupported("Cannot reset object ", id
);
86 status
= ObjectRegistry::NewInstance()->NewSharedObject(id
, result
);
88 status
= Status::NotSupported("Cannot load object in LITE mode ", id
);
91 if (config_options
.ignore_unsupported_options
) {
99 return ConfigurableHelper::ConfigureNewObject(config_options
, result
->get(),
100 id
, curr_opts
, opt_map
);
103 // Creates a new unique customizable instance object based on the input
105 // @see LoadSharedObject for more information on the inner workings of this
108 // @param config_options Controls how the instance is created and errors are
110 // @param value Either the simple name of the instance to create, or a set of
111 // name-value pairs to
112 // create and initailzie the object
113 // @param func Optional function to call to attempt to create an instance
114 // @param result The newly created instance.
115 template <typename T
>
116 static Status
LoadUniqueObject(const ConfigOptions
& config_options
,
117 const std::string
& value
,
118 const UniqueFactoryFunc
<T
>& func
,
119 std::unique_ptr
<T
>* result
) {
121 std::unordered_map
<std::string
, std::string
> opt_map
;
122 Status status
= ConfigurableHelper::GetOptionsMap(value
, &id
, &opt_map
);
123 if (!status
.ok()) { // GetOptionsMap failed
126 std::string curr_opts
;
128 if (result
->get() != nullptr && result
->get()->GetId() == id
) {
129 // Try to get the existing options, ignoring any errors
130 ConfigOptions embedded
= config_options
;
131 embedded
.delimiter
= ";";
132 result
->get()->GetOptionString(embedded
, &curr_opts
).PermitUncheckedError();
135 if (func
== nullptr || !func(id
, result
)) { // No factory, or it failed
136 if (id
.empty() && opt_map
.empty()) {
137 // No Id and no options. Clear the object
140 } else if (id
.empty()) { // We have no Id but have options. Not good
141 return Status::NotSupported("Cannot reset object ", id
);
144 status
= ObjectRegistry::NewInstance()->NewUniqueObject(id
, result
);
146 status
= Status::NotSupported("Cannot load object in LITE mode ", id
);
147 #endif // ROCKSDB_LITE
149 if (config_options
.ignore_unsupported_options
) {
157 return ConfigurableHelper::ConfigureNewObject(config_options
, result
->get(),
158 id
, curr_opts
, opt_map
);
160 // Creates a new static (raw pointer) customizable instance object based on the
162 // @see LoadSharedObject for more information on the inner workings of this
165 // @param config_options Controls how the instance is created and errors are
167 // @param value Either the simple name of the instance to create, or a set of
168 // name-value pairs to
169 // create and initailzie the object
170 // @param func Optional function to call to attempt to create an instance
171 // @param result The newly created instance.
172 template <typename T
>
173 static Status
LoadStaticObject(const ConfigOptions
& config_options
,
174 const std::string
& value
,
175 const StaticFactoryFunc
<T
>& func
, T
** result
) {
177 std::unordered_map
<std::string
, std::string
> opt_map
;
178 Status status
= ConfigurableHelper::GetOptionsMap(value
, &id
, &opt_map
);
179 if (!status
.ok()) { // GetOptionsMap failed
182 std::string curr_opts
;
184 if (*result
!= nullptr && (*result
)->GetId() == id
) {
185 // Try to get the existing options, ignoring any errors
186 ConfigOptions embedded
= config_options
;
187 embedded
.delimiter
= ";";
188 (*result
)->GetOptionString(embedded
, &curr_opts
).PermitUncheckedError();
191 if (func
== nullptr || !func(id
, result
)) { // No factory, or it failed
192 if (id
.empty() && opt_map
.empty()) {
193 // No Id and no options. Clear the object
196 } else if (id
.empty()) { // We have no Id but have options. Not good
197 return Status::NotSupported("Cannot reset object ", id
);
200 status
= ObjectRegistry::NewInstance()->NewStaticObject(id
, result
);
202 status
= Status::NotSupported("Cannot load object in LITE mode ", id
);
203 #endif // ROCKSDB_LITE
205 if (config_options
.ignore_unsupported_options
) {
213 return ConfigurableHelper::ConfigureNewObject(config_options
, *result
, id
,
216 } // namespace ROCKSDB_NAMESPACE