]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/include/rocksdb/utilities/customizable_util.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / include / rocksdb / utilities / customizable_util.h
CommitLineData
1e59de90
TL
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).
5//
6// The methods in this file are used to instantiate new Customizable
7// instances of objects. These methods are most typically used by
8// the "CreateFromString" method of a customizable class.
9// If not developing a new Type of customizable class, you probably
10// do not need the methods in this file.
11//
12// See https://github.com/facebook/rocksdb/wiki/RocksDB-Configurable-Objects
13// for more information on how to develop and use customizable objects
14
15#pragma once
16#include <functional>
17#include <memory>
18#include <unordered_map>
19
20#include "options/configurable_helper.h"
21#include "rocksdb/convenience.h"
22#include "rocksdb/customizable.h"
23#include "rocksdb/status.h"
24#include "rocksdb/utilities/object_registry.h"
25
26namespace ROCKSDB_NAMESPACE {
27// The FactoryFunc functions are used to create a new customizable object
28// without going through the ObjectRegistry. This methodology is especially
29// useful in LITE mode, where there is no ObjectRegistry. The methods take
30// in an ID of the object to create and a pointer to store the created object.
31// If the factory successfully recognized the input ID, the method should return
32// success; otherwise false should be returned. On success, the object
33// parameter contains the new object.
34template <typename T>
35using SharedFactoryFunc =
36 std::function<bool(const std::string&, std::shared_ptr<T>*)>;
37
38template <typename T>
39using UniqueFactoryFunc =
40 std::function<bool(const std::string&, std::unique_ptr<T>*)>;
41
42template <typename T>
43using StaticFactoryFunc = std::function<bool(const std::string&, T**)>;
44
45// Creates a new shared customizable instance object based on the
46// input parameters using the object registry.
47//
48// The id parameter specifies the instance class of the object to create.
49// The opt_map parameter specifies the configuration of the new instance.
50//
51// The config_options parameter controls the process and how errors are
52// returned. If ignore_unknown_options=true, unknown values are ignored during
53// the configuration. If ignore_unsupported_options=true, unknown instance types
54// are ignored. If invoke_prepare_options=true, the resulting instance will be
55// initialized (via PrepareOptions)
56//
57// @param config_options Controls how the instance is created and errors are
58// handled
59// @param id The identifier of the new object being created. This string
60// will be used by the object registry to locate the appropriate object to
61// create.
62// @param opt_map Optional name-value pairs of properties to set for the newly
63// created object
64// @param result The newly created and configured instance.
65template <typename T>
66static Status NewSharedObject(
67 const ConfigOptions& config_options, const std::string& id,
68 const std::unordered_map<std::string, std::string>& opt_map,
69 std::shared_ptr<T>* result) {
70 if (!id.empty()) {
71 Status status;
72#ifndef ROCKSDB_LITE
73 status = config_options.registry->NewSharedObject(id, result);
74#else
75 status = Status::NotSupported("Cannot load object in LITE mode ", id);
76#endif // ROCKSDB_LITE
77 if (config_options.ignore_unsupported_options && status.IsNotSupported()) {
78 status = Status::OK();
79 } else if (status.ok()) {
80 status = Customizable::ConfigureNewObject(config_options, result->get(),
81 opt_map);
82 }
83 return status;
84 } else if (opt_map.empty()) {
85 // There was no ID and no map (everything empty), so reset/clear the result
86 result->reset();
87 return Status::OK();
88 } else {
89 return Status::NotSupported("Cannot reset object ");
90 }
91}
92
93// Creates a new managed customizable instance object based on the
94// input parameters using the object registry. Unlike "shared" objects,
95// managed objects are limited to a single instance per ID.
96//
97// The id parameter specifies the instance class of the object to create.
98// If an object with this id exists in the registry, the existing object
99// will be returned. If the object does not exist, a new one will be created.
100//
101// The opt_map parameter specifies the configuration of the new instance.
102// If the object already exists, the existing object is returned "as is" and
103// this parameter is ignored.
104//
105// The config_options parameter controls the process and how errors are
106// returned. If ignore_unknown_options=true, unknown values are ignored during
107// the configuration. If ignore_unsupported_options=true, unknown instance types
108// are ignored. If invoke_prepare_options=true, the resulting instance will be
109// initialized (via PrepareOptions)
110//
111// @param config_options Controls how the instance is created and errors are
112// handled
113// @param id The identifier of the object. This string
114// will be used by the object registry to locate the appropriate object to
115// create or return.
116// @param opt_map Optional name-value pairs of properties to set for the newly
117// created object
118// @param result The managed instance.
119template <typename T>
120static Status NewManagedObject(
121 const ConfigOptions& config_options, const std::string& id,
122 const std::unordered_map<std::string, std::string>& opt_map,
123 std::shared_ptr<T>* result) {
124 Status status;
125 if (!id.empty()) {
126#ifndef ROCKSDB_LITE
127 status = config_options.registry->GetOrCreateManagedObject<T>(
128 id, result, [config_options, opt_map](T* object) {
129 return object->ConfigureFromMap(config_options, opt_map);
130 });
131#else
132 (void)result;
133 (void)opt_map;
134 status = Status::NotSupported("Cannot load object in LITE mode ", id);
135#endif // ROCKSDB_LITE
136 if (config_options.ignore_unsupported_options && status.IsNotSupported()) {
137 return Status::OK();
138 }
139 } else {
140 status = Status::NotSupported("Cannot reset object ");
141 }
142 return status;
143}
144
145// Creates a new shared Customizable object based on the input parameters.
146// This method parses the input value to determine the type of instance to
147// create. If there is an existing instance (in result) and it is the same ID
148// as the object being created, the existing configuration is stored and used as
149// the default for the new object.
150//
151// The value parameter specified the instance class of the object to create.
152// If it is a simple string (e.g. BlockBasedTable), then the instance will be
153// created using the default settings. If the value is a set of name-value
154// pairs, then the "id" value is used to determine the instance to create and
155// the remaining parameters are used to configure the object. Id name-value
156// pairs are specified, there should be an "id=value" pairing or an error may
157// result.
158//
159// The config_options parameter controls the process and how errors are
160// returned. If ignore_unknown_options=true, unknown values are ignored during
161// the configuration. If ignore_unsupported_options=true, unknown instance types
162// are ignored. If invoke_prepare_options=true, the resulting instance will be
163// initialized (via PrepareOptions)
164//
165// @param config_options Controls how the instance is created and errors are
166// handled
167// @param value Either the simple name of the instance to create, or a set of
168// name-value pairs to create and initailize the object
169// @param func Optional function to call to attempt to create an instance
170// @param result The newly created instance.
171template <typename T>
172static Status LoadSharedObject(const ConfigOptions& config_options,
173 const std::string& value,
174 const SharedFactoryFunc<T>& func,
175 std::shared_ptr<T>* result) {
176 std::string id;
177 std::unordered_map<std::string, std::string> opt_map;
178
179 Status status = Customizable::GetOptionsMap(config_options, result->get(),
180 value, &id, &opt_map);
181 if (!status.ok()) { // GetOptionsMap failed
182 return status;
183 } else if (func == nullptr ||
184 !func(id, result)) { // No factory, or it failed
185 return NewSharedObject(config_options, id, opt_map, result);
186 } else {
187 return Customizable::ConfigureNewObject(config_options, result->get(),
188 opt_map);
189 }
190}
191
192// Creates a new shared Customizable object based on the input parameters.
193//
194// The value parameter specified the instance class of the object to create.
195// If it is a simple string (e.g. BlockBasedTable), then the instance will be
196// created using the default settings. If the value is a set of name-value
197// pairs, then the "id" value is used to determine the instance to create and
198// the remaining parameters are used to configure the object. Id name-value
199// pairs are specified, there should be an "id=value" pairing or an error may
200// result.
201//
202// The "id" field from the value (either the whole field or "id=XX") is used
203// to determine the type/id of the object to return. For a given id, there
204// the same instance of the object will be returned from this method (as opposed
205// to LoadSharedObject which would create different objects for the same id.
206//
207// The config_options parameter controls the process and how errors are
208// returned. If ignore_unknown_options=true, unknown values are ignored during
209// the configuration. If ignore_unsupported_options=true, unknown instance types
210// are ignored. If invoke_prepare_options=true, the resulting instance will be
211// initialized (via PrepareOptions)
212//
213// @param config_options Controls how the instance is created and errors are
214// handled
215// @param value Either the simple name of the instance to create, or a set of
216// name-value pairs to create and initailize the object
217// @param func Optional function to call to attempt to create an instance
218// @param result The newly created instance.
219template <typename T>
220static Status LoadManagedObject(const ConfigOptions& config_options,
221 const std::string& value,
222 std::shared_ptr<T>* result) {
223 std::string id;
224 std::unordered_map<std::string, std::string> opt_map;
225 Status status = Customizable::GetOptionsMap(config_options, nullptr, value,
226 &id, &opt_map);
227 if (!status.ok()) { // GetOptionsMap failed
228 return status;
229 } else if (value.empty()) { // No Id and no options. Clear the object
230 *result = nullptr;
231 return Status::OK();
232 } else {
233 return NewManagedObject(config_options, id, opt_map, result);
234 }
235}
236
237// Creates a new unique pointer customizable instance object based on the
238// input parameters using the object registry.
239// @see NewSharedObject for more information on the inner workings of this
240// method.
241//
242// @param config_options Controls how the instance is created and errors are
243// handled
244// @param id The identifier of the new object being created. This string
245// will be used by the object registry to locate the appropriate object to
246// create.
247// @param opt_map Optional name-value pairs of properties to set for the newly
248// created object
249// @param result The newly created and configured instance.
250template <typename T>
251static Status NewUniqueObject(
252 const ConfigOptions& config_options, const std::string& id,
253 const std::unordered_map<std::string, std::string>& opt_map,
254 std::unique_ptr<T>* result) {
255 if (!id.empty()) {
256 Status status;
257#ifndef ROCKSDB_LITE
258 status = config_options.registry->NewUniqueObject(id, result);
259#else
260 status = Status::NotSupported("Cannot load object in LITE mode ", id);
261#endif // ROCKSDB_LITE
262 if (config_options.ignore_unsupported_options && status.IsNotSupported()) {
263 status = Status::OK();
264 } else if (status.ok()) {
265 status = Customizable::ConfigureNewObject(config_options, result->get(),
266 opt_map);
267 }
268 return status;
269 } else if (opt_map.empty()) {
270 // There was no ID and no map (everything empty), so reset/clear the result
271 result->reset();
272 return Status::OK();
273 } else {
274 return Status::NotSupported("Cannot reset object ");
275 }
276}
277
278// Creates a new unique customizable instance object based on the input
279// parameters.
280// @see LoadSharedObject for more information on the inner workings of this
281// method.
282//
283// @param config_options Controls how the instance is created and errors are
284// handled
285// @param value Either the simple name of the instance to create, or a set of
286// name-value pairs to create and initailize the object
287// @param func Optional function to call to attempt to create an instance
288// @param result The newly created instance.
289template <typename T>
290static Status LoadUniqueObject(const ConfigOptions& config_options,
291 const std::string& value,
292 const UniqueFactoryFunc<T>& func,
293 std::unique_ptr<T>* result) {
294 std::string id;
295 std::unordered_map<std::string, std::string> opt_map;
296 Status status = Customizable::GetOptionsMap(config_options, result->get(),
297 value, &id, &opt_map);
298 if (!status.ok()) { // GetOptionsMap failed
299 return status;
300 } else if (func == nullptr ||
301 !func(id, result)) { // No factory, or it failed
302 return NewUniqueObject(config_options, id, opt_map, result);
303 } else {
304 return Customizable::ConfigureNewObject(config_options, result->get(),
305 opt_map);
306 }
307}
308
309// Creates a new static (raw pointer) customizable instance object based on the
310// input parameters using the object registry.
311// @see NewSharedObject for more information on the inner workings of this
312// method.
313//
314// @param config_options Controls how the instance is created and errors are
315// handled
316// @param id The identifier of the new object being created. This string
317// will be used by the object registry to locate the appropriate object to
318// create.
319// @param opt_map Optional name-value pairs of properties to set for the newly
320// created object
321// @param result The newly created and configured instance.
322template <typename T>
323static Status NewStaticObject(
324 const ConfigOptions& config_options, const std::string& id,
325 const std::unordered_map<std::string, std::string>& opt_map, T** result) {
326 if (!id.empty()) {
327 Status status;
328#ifndef ROCKSDB_LITE
329 status = config_options.registry->NewStaticObject(id, result);
330#else
331 status = Status::NotSupported("Cannot load object in LITE mode ", id);
332#endif // ROCKSDB_LITE
333 if (config_options.ignore_unsupported_options && status.IsNotSupported()) {
334 status = Status::OK();
335 } else if (status.ok()) {
336 status =
337 Customizable::ConfigureNewObject(config_options, *result, opt_map);
338 }
339 return status;
340 } else if (opt_map.empty()) {
341 // There was no ID and no map (everything empty), so reset/clear the result
342 *result = nullptr;
343 return Status::OK();
344 } else {
345 return Status::NotSupported("Cannot reset object ");
346 }
347}
348
349// Creates a new static (raw pointer) customizable instance object based on the
350// input parameters.
351// @see LoadSharedObject for more information on the inner workings of this
352// method.
353//
354// @param config_options Controls how the instance is created and errors are
355// handled
356// @param value Either the simple name of the instance to create, or a set of
357// name-value pairs to create and initailize the object
358// @param func Optional function to call to attempt to create an instance
359// @param result The newly created instance.
360template <typename T>
361static Status LoadStaticObject(const ConfigOptions& config_options,
362 const std::string& value,
363 const StaticFactoryFunc<T>& func, T** result) {
364 std::string id;
365 std::unordered_map<std::string, std::string> opt_map;
366 Status status = Customizable::GetOptionsMap(config_options, *result, value,
367 &id, &opt_map);
368 if (!status.ok()) { // GetOptionsMap failed
369 return status;
370 } else if (func == nullptr ||
371 !func(id, result)) { // No factory, or it failed
372 return NewStaticObject(config_options, id, opt_map, result);
373 } else {
374 return Customizable::ConfigureNewObject(config_options, *result, opt_map);
375 }
376}
377} // namespace ROCKSDB_NAMESPACE