summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/include/rocksdb/customizable.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/rocksdb/include/rocksdb/customizable.h
parentInitial commit. (diff)
downloadceph-upstream/18.2.2.tar.xz
ceph-upstream/18.2.2.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/rocksdb/include/rocksdb/customizable.h')
-rw-r--r--src/rocksdb/include/rocksdb/customizable.h233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/rocksdb/include/rocksdb/customizable.h b/src/rocksdb/include/rocksdb/customizable.h
new file mode 100644
index 000000000..92f7504ae
--- /dev/null
+++ b/src/rocksdb/include/rocksdb/customizable.h
@@ -0,0 +1,233 @@
+// 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 "rocksdb/configurable.h"
+#include "rocksdb/status.h"
+
+namespace ROCKSDB_NAMESPACE {
+/**
+ * Customizable a base class used by the rocksdb that describes a
+ * standard way of configuring and creating objects. Customizable objects
+ * are configurable objects that can be created from an ObjectRegistry.
+ *
+ * Customizable classes are used when there are multiple potential
+ * implementations of a class for use by RocksDB (e.g. Table, Cache,
+ * MergeOperator, etc). The abstract base class is expected to define a method
+ * declaring its type and a factory method for creating one of these, such as:
+ * static const char *Type() { return "Table"; }
+ * static Status CreateFromString(const ConfigOptions& options,
+ * const std::string& id,
+ * std::shared_ptr<TableFactory>* result);
+ * The "Type" string is expected to be unique (no two base classes are the same
+ * type). This factory is expected, based on the options and id, create and
+ * return the appropriate derived type of the customizable class (e.g.
+ * BlockBasedTableFactory, PlainTableFactory, etc). For extension developers,
+ * helper classes and methods are provided for writing this factory.
+ *
+ * Instances of a Customizable class need to define:
+ * - A "static const char *kClassName()" method. This method defines the name
+ * of the class instance (e.g. BlockBasedTable, LRUCache) and is used by the
+ * CheckedCast method.
+ * - The Name() of the object. This name is used when creating and saving
+ * instances of this class. Typically this name will be the same as
+ * kClassName().
+ *
+ * Additionally, Customizable classes should register any options used to
+ * configure themselves with the Configurable subsystem.
+ *
+ * When a Customizable is being created, the "name" property specifies
+ * the name of the instance being created.
+ * For custom objects, their configuration and name can be specified by:
+ * [prop]={name=X;option 1 = value1[; option2=value2...]}
+ *
+ * [prop].name=X
+ * [prop].option1 = value1
+ *
+ * [prop].name=X
+ * X.option1 =value1
+ */
+class Customizable : public Configurable {
+ public:
+ ~Customizable() override {}
+
+ // Returns the name of this class of Customizable
+ virtual const char* Name() const = 0;
+
+ // Returns an identifier for this Customizable.
+ // This could be its name or something more complex (like its URL/pattern).
+ // Used for pretty printing.
+ virtual std::string GetId() const {
+ std::string id = Name();
+ return id;
+ }
+
+ // This is typically determined by if the input name matches the
+ // name of this object.
+ // This method is typically used in conjunction with CheckedCast to find the
+ // derived class instance from its base. For example, if you have an Env
+ // and want the "Default" env, you would IsInstanceOf("Default") to get
+ // the default implementation. This method should be used when you need a
+ // specific derivative or implementation of a class.
+ //
+ // Intermediary caches (such as SharedCache) may wish to override this method
+ // to check for the intermediary name (SharedCache). Classes with multiple
+ // potential names (e.g. "PosixEnv", "DefaultEnv") may also wish to override
+ // this method.
+ //
+ // Note that IsInstanceOf only uses the "is-a" relationship and not "has-a".
+ // Wrapped classes that have an Inner "has-a" should not be returned.
+ //
+ // @param name The name of the instance to find.
+ // Returns true if the class is an instance of the input name.
+ virtual bool IsInstanceOf(const std::string& name) const {
+ if (name.empty()) {
+ return false;
+ } else if (name == Name()) {
+ return true;
+ } else {
+ const char* nickname = NickName();
+ if (nickname != nullptr && name == nickname) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ const void* GetOptionsPtr(const std::string& name) const override {
+ const void* ptr = Configurable::GetOptionsPtr(name);
+ if (ptr != nullptr) {
+ return ptr;
+ } else {
+ const auto inner = Inner();
+ if (inner != nullptr) {
+ return inner->GetOptionsPtr(name);
+ } else {
+ return nullptr;
+ }
+ }
+ }
+
+ // Returns the named instance of the Customizable as a T*, or nullptr if not
+ // found. This method uses IsInstanceOf/Inner to find the appropriate class
+ // instance and then casts it to the expected return type.
+ template <typename T>
+ const T* CheckedCast() const {
+ if (IsInstanceOf(T::kClassName())) {
+ return static_cast<const T*>(this);
+ } else {
+ const auto inner = Inner();
+ if (inner != nullptr) {
+ return inner->CheckedCast<T>();
+ } else {
+ return nullptr;
+ }
+ }
+ }
+
+ template <typename T>
+ T* CheckedCast() {
+ if (IsInstanceOf(T::kClassName())) {
+ return static_cast<T*>(this);
+ } else {
+ auto inner = const_cast<Customizable*>(Inner());
+ if (inner != nullptr) {
+ return inner->CheckedCast<T>();
+ } else {
+ return nullptr;
+ }
+ }
+ }
+
+ // Checks to see if this Customizable 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.
+ // @see Configurable::AreEquivalent for more details
+ bool AreEquivalent(const ConfigOptions& config_options,
+ const Configurable* other,
+ std::string* mismatch) const override;
+#ifndef ROCKSDB_LITE
+ // Gets the value of the option associated with the input name
+ // @see Configurable::GetOption for more details
+ Status GetOption(const ConfigOptions& config_options, const std::string& name,
+ std::string* value) const override;
+#endif // ROCKSDB_LITE
+ // Helper method for getting for parsing the opt_value into the corresponding
+ // options for use in potentially creating a new Customizable object (this
+ // method is primarily a support method for LoadSharedObject et al for new
+ // Customizable objects). The opt_value may be either name-value pairs
+ // separated by ";" (a=b; c=d), or a simple name (a). In order to create a new
+ // Customizable, the ID is determined by:
+ // - If the value is a simple name (e.g. "BlockBasedTable"), the id is this
+ // name;
+ // - Otherwise, if there is a "id=value", the id is set to "value"
+ // - Otherwise, if the input customizable is not null, custom->GetId is used
+ // - Otherwise, an error is returned.
+ //
+ // If the opt_value is name-value pairs, these pairs will be returned in
+ // options (without the id pair). If the ID being returned matches the ID of
+ // the input custom object, then the options from the input object will also
+ // be added to the returned options.
+ //
+ // This method returns non-OK if the ID could not be found, or if the
+ // opt_value could not be parsed into name-value pairs.
+ static Status GetOptionsMap(
+ const ConfigOptions& config_options, const Customizable* custom,
+ const std::string& opt_value, std::string* id,
+ std::unordered_map<std::string, std::string>* options);
+
+ // Helper method to configure a new object with the supplied options.
+ // If the object is not null and invoke_prepare_options=true, the object
+ // will be configured and prepared.
+ // Returns success if the object is properly configured and (optionally)
+ // prepared Returns InvalidArgument if the object is nullptr and there are
+ // options in the map Returns the result of the ConfigureFromMap or
+ // PrepareOptions
+ static Status ConfigureNewObject(
+ const ConfigOptions& config_options, Customizable* object,
+ const std::unordered_map<std::string, std::string>& options);
+
+ // Returns the inner class when a Customizable implements a has-a (wrapped)
+ // relationship. Derived classes that implement a has-a must override this
+ // method in order to get CheckedCast to function properly.
+ virtual const Customizable* Inner() const { return nullptr; }
+
+ protected:
+ // Generates a ID specific for this instance of the customizable.
+ // The unique ID is of the form <name>:<addr>#pid, where:
+ // - name is the Name() of this object;
+ // - addr is the memory address of this object;
+ // - pid is the process ID of this process ID for this process.
+ // Note that if obj1 and obj2 have the same unique IDs, they must be the
+ // same. However, if an object is deleted and recreated, it may have the
+ // same unique ID as a predecessor
+ //
+ // This method is useful for objects (especially ManagedObjects) that
+ // wish to generate an ID that is specific for this instance and wish to
+ // override the GetId() method.
+ std::string GenerateIndividualId() const;
+
+ // Some classes have both a class name (e.g. PutOperator) and a nickname
+ // (e.g. put). Classes can override this method to return a
+ // nickname. Nicknames can be used by InstanceOf and object creation.
+ virtual const char* NickName() const { return ""; }
+ // Given a name (e.g. rocksdb.my.type.opt), returns the short name (opt)
+ std::string GetOptionName(const std::string& long_name) const override;
+#ifndef ROCKSDB_LITE
+ std::string SerializeOptions(const ConfigOptions& options,
+ const std::string& prefix) const override;
+#endif // ROCKSDB_LITE
+};
+
+} // namespace ROCKSDB_NAMESPACE