fork of https://github.com/rust-rocksdb/rust-rocksdb for nextgraph
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
391 lines
19 KiB
391 lines
19 KiB
1 year ago
|
// 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;
|
||
|
// The map of options being registered
|
||
|
const std::unordered_map<std::string, OptionTypeInfo>* type_map;
|
||
|
};
|
||
|
|
||
|
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);
|
||
|
|
||
|
// 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);
|
||
|
|
||
|
// 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;
|
||
|
// 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;
|
||
|
|
||
|
// 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);
|
||
|
|
||
|
// 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;
|
||
|
// 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;
|
||
|
|
||
|
// 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
|