-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfigurable.h
400 lines (373 loc) · 19.2 KB
/
configurable.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#pragma once
#include <atomic>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "rocksdb/rocksdb_namespace.h"
#include "rocksdb/status.h"
namespace ROCKSDB_NAMESPACE {
class Logger;
class ObjectRegistry;
class OptionTypeInfo;
struct ColumnFamilyOptions;
struct ConfigOptions;
struct DBOptions;
// Configurable is a base class used by the rocksdb that describes a
// standard way of configuring objects. A Configurable object can:
// -> Populate itself given:
// - One or more "name/value" pair strings
// - A string representing the set of name=value properties
// - A map of name/value properties.
// -> Convert itself into its string representation
// -> Dump itself to a Logger
// -> Compare itself to another Configurable object to see if the two objects
// have equivalent options settings
//
// If a derived class calls RegisterOptions to register (by name) how its
// options objects are to be processed, this functionality can typically be
// handled by this class without additional overrides. Otherwise, the derived
// class will need to implement the methods for handling the corresponding
// functionality.
class Configurable {
protected:
friend class ConfigurableHelper;
struct RegisteredOptions {
// The name of the options being registered
std::string name;
// Pointer to the object being registered
void* opt_ptr;
#ifndef ROCKSDB_LITE
// The map of options being registered
const std::unordered_map<std::string, OptionTypeInfo>* type_map;
#endif
};
public:
virtual ~Configurable() {}
// Returns the raw pointer of the named options that is used by this
// object, or nullptr if this function is not supported.
// Since the return value is a raw pointer, the object owns the
// pointer and the caller should not delete the pointer.
//
// Note that changing the underlying options while the object
// is currently used by any open DB is undefined behavior.
// Developers should use DB::SetOption() instead to dynamically change
// options while the DB is open.
template <typename T>
const T* GetOptions() const {
return GetOptions<T>(T::kName());
}
template <typename T>
T* GetOptions() {
return GetOptions<T>(T::kName());
}
template <typename T>
const T* GetOptions(const std::string& name) const {
return reinterpret_cast<const T*>(GetOptionsPtr(name));
}
template <typename T>
T* GetOptions(const std::string& name) {
return reinterpret_cast<T*>(const_cast<void*>(GetOptionsPtr(name)));
}
// Configures the options for this class based on the input parameters.
// On successful completion, the object is updated with the settings from
// the opt_map.
// If this method fails, an attempt is made to revert the object to original
// state. Note that the revert may not be the original state but may be an
// equivalent. For example, if the object contains an option that is a
// shared_ptr, the shared_ptr may not be the original one but a copy (e.g. not
// the Cache object that was passed in, but a Cache object of the same size).
//
// The acceptable values of the name/value pairs are documented with the
// specific class/instance.
//
// @param config_options Controls how the arguments are processed.
// @param opt_map Name/value pairs of the options to update
// @param unused If specified, this value will return the name/value
// pairs from opt_map that were NotFound for this object.
// @return OK If all values in the map were successfully updated
// If invoke_prepare_options is true, OK also implies
// PrepareOptions ran successfully.
// @return NotFound If any of the names in the opt_map were not valid
// for this object. If unused is specified, it will contain the
// collection of NotFound names.
// @return NotSupported If any of the names are valid but the object does
// not know how to convert the value. This can happen if, for example,
// there is some nested Configurable that cannot be created.
// @return InvalidArgument If any of the values cannot be successfully
// parsed. This can also be returned if PrepareOptions encounters an
// error.
// @see ConfigOptions for a description of the controls.
Status ConfigureFromMap(
const ConfigOptions& config_options,
const std::unordered_map<std::string, std::string>& opt_map);
Status ConfigureFromMap(
const ConfigOptions& config_options,
const std::unordered_map<std::string, std::string>& opt_map,
std::unordered_map<std::string, std::string>* unused);
#ifndef ROCKSDB_LITE
// Updates the named option to the input value, returning OK if successful.
// Note that ConfigureOption does not cause PrepareOptions to be invoked.
// @param config_options Controls how the name/value is processed.
// @param name The name of the option to update
// @param value The value to set for the named option
// @return OK If the named field was successfully updated to value.
// @return NotFound If the name is not valid for this object.
// @return NotSupported If the name is valid but the object does
// not know how to convert the value. This can happen if, for example,
// there is some nested Configurable that cannot be created.
// @return InvalidArgument If the value cannot be successfully parsed.
Status ConfigureOption(const ConfigOptions& config_options,
const std::string& name, const std::string& value);
#endif // ROCKSDB_LITE
// Configures the options for this class based on the input parameters.
// On successful completion, the object is updated with the settings from
// the opt_map. If this method fails, an attempt is made to revert the
// object to original state. Note that the revert may not be the original
// state but may be an equivalent.
// @see ConfigureFromMap for more details
// @param config_options Controls how the arguments are processed.
// @param opt_str string containing the values to update.
// @param unused If specified, this value will return the name/value
// pairs from opt_map that were NotFound for this object.
// @return OK If all specified values were successfully updated
// If invoke_prepare_options is true, OK also implies
// PrepareOptions ran successfully.
// @return NotFound If any of the names were not valid for this object.
// If unused is specified, it will contain the collection of NotFound
// names.
// @return NotSupported If any of the names are valid but the object does
// not know how to convert the value. This can happen if, for example,
// there is some nested Configurable that cannot be created.
// @return InvalidArgument If any of the values cannot be successfully
// parsed. This can also be returned if PrepareOptions encounters an
// error.
Status ConfigureFromString(const ConfigOptions& config_options,
const std::string& opts);
// Fills in result with the serialized options for this object.
// This is the inverse of ConfigureFromString.
// @param config_options Controls how serialization happens.
// @param result The string representation of this object.
// @return OK If the options for this object were successfully serialized.
// @return InvalidArgument If one or more of the options could not be
// serialized.
Status GetOptionString(const ConfigOptions& config_options,
std::string* result) const;
#ifndef ROCKSDB_LITE
// Returns the serialized options for this object.
// This method is similar to GetOptionString with no errors.
// @param config_options Controls how serialization happens.
// @param prefix A string to prepend to every option.
// @return The serialized representation of the options for this object
std::string ToString(const ConfigOptions& config_options) const {
return ToString(config_options, "");
}
std::string ToString(const ConfigOptions& config_options,
const std::string& prefix) const;
// Returns the list of option names associated with this configurable
// @param config_options Controls how the names are returned
// @param result The set of option names for this object. Note that
// options that are deprecated or aliases are not returned.
// @return OK on success.
Status GetOptionNames(const ConfigOptions& config_options,
std::unordered_set<std::string>* result) const;
// Returns the value of the option associated with the input name
// This method is the functional inverse of ConfigureOption
// @param config_options Controls how the value is returned
// @param name The name of the option to return a value for.
// @param value The returned value associated with the named option.
// @return OK If the named field was successfully updated to value.
// @return NotFound If the name is not valid for this object.
// @param InvalidArgument If the name is valid for this object but
// its value cannot be serialized.
virtual Status GetOption(const ConfigOptions& config_options,
const std::string& name, std::string* value) const;
#endif // ROCKSDB_LITE
// Checks to see if this Configurable is equivalent to other.
// This method assumes that the two objects are of the same class.
// @param config_options Controls how the options are compared.
// @param other The other object to compare to.
// @param mismatch If the objects do not match, this parameter contains
// the name of the option that triggered the match failure.
// @param True if the objects match, false otherwise.
virtual bool AreEquivalent(const ConfigOptions& config_options,
const Configurable* other,
std::string* name) const;
// Returns a pretty-printed, human-readable version of the options.
// This method is typically used to dump the options to a log file.
// Classes should override this method
virtual std::string GetPrintableOptions() const { return ""; }
// Validates that the settings are valid/consistent and performs any object
// initialization required by this object. This method may be called as part
// of Configure (if invoke_prepare_options is set), or may be invoked
// separately.
//
// Once an object has been prepared, non-mutable options can no longer be
// updated.
//
// Classes must override this method to provide any implementation-specific
// initialization, such as opening log files or setting up cache parameters.
// Implementations should be idempotent (e.g. don't re-open the log file or
// reconfigure the cache), as there is the potential this method can be called
// more than once.
//
// By default, this method will also prepare all nested (Inner and
// OptionType::kConfigurable) objects.
//
// @param config_options Controls how the object is prepared. Also contains
// a Logger and Env that can be used to initialize this object.
// @return OK If the object was successfully initialized.
// @return InvalidArgument If this object could not be successfully
// initialized.
virtual Status PrepareOptions(const ConfigOptions& config_options);
// Checks to see if the settings are valid for this object.
// This method checks to see if the input DBOptions and ColumnFamilyOptions
// are valid for the settings of this object. For example, an Env might not
// support certain mmap modes or a TableFactory might require certain
// settings.
//
// By default, this method will also validate all nested (Inner and
// OptionType::kConfigurable) objects.
//
// @param db_opts The DBOptions to validate
// @param cf_opts The ColumnFamilyOptions to validate
// @return OK if the options are valid
// @return InvalidArgument If the arguments are not valid for the options
// of the current object.
virtual Status ValidateOptions(const DBOptions& db_opts,
const ColumnFamilyOptions& cf_opts) const;
// Splits the input opt_value into the ID field and the remaining options.
// The input opt_value can be in the form of "name" or "name=value
// [;name=value]". The first form uses the "name" as an id with no options The
// latter form converts the input into a map of name=value pairs and sets "id"
// to the "id" value from the map.
// @param opt_value The value to split into id and options
// @param id The id field from the opt_value
// @param options The remaining name/value pairs from the opt_value
// @param default_id If specified and there is no id field in the map, this
// value is returned as the ID
// @return OK if the value was converted to a map successfully and an ID was
// found.
// @return InvalidArgument if the value could not be converted to a map or
// there was or there is no id property in the map.
static Status GetOptionsMap(
const std::string& opt_value, const std::string& default_id,
std::string* id, std::unordered_map<std::string, std::string>* options);
protected:
// Returns the raw pointer for the associated named option.
// The name is typically the name of an option registered via the
// Classes may override this method to provide further specialization (such as
// returning a sub-option)
//
// The default implementation looks at the registered options. If the
// input name matches that of a registered option, the pointer registered
// with that name is returned.
// e.g,, RegisterOptions("X", &my_ptr, ...); GetOptionsPtr("X") returns
// "my_ptr"
virtual const void* GetOptionsPtr(const std::string& name) const;
// Method for allowing options to be configured outside of the normal
// registered options framework. Classes may override this method if they
// wish to support non-standard options implementations (such as configuring
// themselves from constant or simple ":"-separated strings.
//
// The default implementation does nothing and returns OK
virtual Status ParseStringOptions(const ConfigOptions& config_options,
const std::string& opts_str);
// Internal method to configure an object from a map of name-value options.
// This method uses the input config_options to drive the configuration of
// the options in opt_map. Any option name that cannot be found from the
// input set will be returned in "unused".
//
// Classes may override this method to extend the functionality if required.
// @param config_options Controls how the options are configured and errors
// handled.
// @param opts_map The set of options to configure
// @param unused Any options from opt_map that were not configured.
// @returns a Status based on the rules outlined in ConfigureFromMap
virtual Status ConfigureOptions(
const ConfigOptions& config_options,
const std::unordered_map<std::string, std::string>& opts_map,
std::unordered_map<std::string, std::string>* unused);
#ifndef ROCKSDB_LITE
// Method that configures a the specific opt_name from opt_value.
// By default, this method calls opt_info.ParseOption with the
// input parameters.
// Classes may override this method to extend the functionality, or
// change the returned Status.
virtual Status ParseOption(const ConfigOptions& config_options,
const OptionTypeInfo& opt_info,
const std::string& opt_name,
const std::string& opt_value, void* opt_ptr);
// Internal method to see if the single option name/info matches for this and
// that Classes may override this value to change its behavior.
// @param config_options Controls how the options are being matched
// @param opt_info The OptionTypeInfo registered for this option name
// that controls what field is matched (offset) and how (type).
// @param name The name associated with this opt_info.
// @param this_ptr The base pointer to compare to. This is the object
// registered for
// for this OptionTypeInfo.
// @param that_ptr The other pointer to compare to. This is the object
// registered for
// for this OptionTypeInfo.
// @param bad_name If the match fails, the name of the option that failed to
// match.
virtual bool OptionsAreEqual(const ConfigOptions& config_options,
const OptionTypeInfo& opt_info,
const std::string& name,
const void* const this_ptr,
const void* const that_ptr,
std::string* bad_name) const;
#endif
#ifndef ROCKSDB_LITE
// Internal method to serialize options (ToString)
// Classes may override this value to change its behavior.
virtual std::string SerializeOptions(const ConfigOptions& config_options,
const std::string& header) const;
#endif // ROCKSDB_LITE
// Given a name (e.g. rocksdb.my.type.opt), returns the short name (opt)
virtual std::string GetOptionName(const std::string& long_name) const;
// Registers the input name with the options and associated map.
// When classes register their options in this manner, most of the
// functionality (excluding unknown options and validate/prepare) is
// implemented by the base class.
//
// This method should be called in the class constructor to register the
// option set for this object. For example, to register the options
// associated with the BlockBasedTableFactory, the constructor calls this
// method passing in:
// - the name of the options ("BlockBasedTableOptions");
// - the options object (the BlockBasedTableOptions object for this object;
// - the options type map for the BlockBasedTableOptions.
// This registration allows the Configurable class to process the option
// values associated with the BlockBasedTableOptions without further code in
// the derived class.
//
// @param name The name of this set of options (@see GetOptionsPtr)
// @param opt_ptr Pointer to the options to associate with this name
// @param opt_map Options map that controls how this option is configured.
template <typename T>
void RegisterOptions(
T* opt_ptr,
const std::unordered_map<std::string, OptionTypeInfo>* opt_map) {
RegisterOptions(T::kName(), opt_ptr, opt_map);
}
void RegisterOptions(
const std::string& name, void* opt_ptr,
const std::unordered_map<std::string, OptionTypeInfo>* opt_map);
// Returns true if there are registered options for this Configurable object
inline bool HasRegisteredOptions() const { return !options_.empty(); }
private:
// Contains the collection of options (name, opt_ptr, opt_map) associated with
// this object. This collection is typically set in the constructor of the
// Configurable option via
std::vector<RegisteredOptions> options_;
};
} // namespace ROCKSDB_NAMESPACE