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.
 
 
 
 
 
 
rocksdb/include/rocksdb/configurable.h

398 lines
19 KiB

// 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);
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