37ec9d0c12
Summary: 1. Removed the options from the Capped/Fixed SliceTransforms. Instead these classes are created with id.number. This allows the GetID() id to be calculated and stored at class construction time. This change puts the construction back to similar to how it was prior to the Customizable changes for SliceTransform. 2. Improve the performance of AsString by using the ID only if there are no option properties (which is the case for all of the builtin transforms). Ran tests of calling AsString in a loop 5M times and found approximately a 10x performance increase vs the original code. Pull Request resolved: https://github.com/facebook/rocksdb/pull/9401 Reviewed By: pdillinger Differential Revision: D33668672 Pulled By: mrambacher fbshipit-source-id: d0075912c6ece8ed754ee543bc6b0b49a169b309
401 lines
19 KiB
C++
401 lines
19 KiB
C++
// 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
|