]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/options/customizable_helper.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / rocksdb / options / customizable_helper.h
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 #pragma once
7 #include <functional>
8 #include <memory>
9 #include <unordered_map>
10
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"
17
18 namespace ROCKSDB_NAMESPACE {
19 template <typename T>
20 using SharedFactoryFunc =
21 std::function<bool(const std::string&, std::shared_ptr<T>*)>;
22
23 template <typename T>
24 using UniqueFactoryFunc =
25 std::function<bool(const std::string&, std::unique_ptr<T>*)>;
26
27 template <typename T>
28 using StaticFactoryFunc = std::function<bool(const std::string&, T**)>;
29
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.
35 //
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
42 // result.
43 //
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
49 //
50 // @param config_options Controls how the instance is created and errors are
51 // handled
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.
57 template <typename T>
58 static Status LoadSharedObject(const ConfigOptions& config_options,
59 const std::string& value,
60 const SharedFactoryFunc<T>& func,
61 std::shared_ptr<T>* result) {
62 std::string id;
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
66 return status;
67 }
68 std::string curr_opts;
69 #ifndef ROCKSDB_LITE
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();
75 }
76 #endif
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
80 result->reset();
81 return Status::OK();
82 } else if (id.empty()) { // We have no Id but have options. Not good
83 return Status::NotSupported("Cannot reset object ", id);
84 } else {
85 #ifndef ROCKSDB_LITE
86 status = ObjectRegistry::NewInstance()->NewSharedObject(id, result);
87 #else
88 status = Status::NotSupported("Cannot load object in LITE mode ", id);
89 #endif
90 if (!status.ok()) {
91 if (config_options.ignore_unsupported_options) {
92 return Status::OK();
93 } else {
94 return status;
95 }
96 }
97 }
98 }
99 return ConfigurableHelper::ConfigureNewObject(config_options, result->get(),
100 id, curr_opts, opt_map);
101 }
102
103 // Creates a new unique customizable instance object based on the input
104 // parameters.
105 // @see LoadSharedObject for more information on the inner workings of this
106 // method.
107 //
108 // @param config_options Controls how the instance is created and errors are
109 // handled
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) {
120 std::string id;
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
124 return status;
125 }
126 std::string curr_opts;
127 #ifndef ROCKSDB_LITE
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();
133 }
134 #endif
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
138 result->reset();
139 return Status::OK();
140 } else if (id.empty()) { // We have no Id but have options. Not good
141 return Status::NotSupported("Cannot reset object ", id);
142 } else {
143 #ifndef ROCKSDB_LITE
144 status = ObjectRegistry::NewInstance()->NewUniqueObject(id, result);
145 #else
146 status = Status::NotSupported("Cannot load object in LITE mode ", id);
147 #endif // ROCKSDB_LITE
148 if (!status.ok()) {
149 if (config_options.ignore_unsupported_options) {
150 return Status::OK();
151 } else {
152 return status;
153 }
154 }
155 }
156 }
157 return ConfigurableHelper::ConfigureNewObject(config_options, result->get(),
158 id, curr_opts, opt_map);
159 }
160 // Creates a new static (raw pointer) customizable instance object based on the
161 // input parameters.
162 // @see LoadSharedObject for more information on the inner workings of this
163 // method.
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
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) {
176 std::string id;
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
180 return status;
181 }
182 std::string curr_opts;
183 #ifndef ROCKSDB_LITE
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();
189 }
190 #endif
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
194 *result = nullptr;
195 return Status::OK();
196 } else if (id.empty()) { // We have no Id but have options. Not good
197 return Status::NotSupported("Cannot reset object ", id);
198 } else {
199 #ifndef ROCKSDB_LITE
200 status = ObjectRegistry::NewInstance()->NewStaticObject(id, result);
201 #else
202 status = Status::NotSupported("Cannot load object in LITE mode ", id);
203 #endif // ROCKSDB_LITE
204 if (!status.ok()) {
205 if (config_options.ignore_unsupported_options) {
206 return Status::OK();
207 } else {
208 return status;
209 }
210 }
211 }
212 }
213 return ConfigurableHelper::ConfigureNewObject(config_options, *result, id,
214 curr_opts, opt_map);
215 }
216 } // namespace ROCKSDB_NAMESPACE