]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/include/rocksdb/customizable.h
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / rocksdb / include / rocksdb / customizable.h
CommitLineData
20effc67
TL
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style license that can be
7// found in the LICENSE file. See the AUTHORS file for names of contributors.
8
9#pragma once
10
11#include "rocksdb/configurable.h"
12#include "rocksdb/status.h"
13
14namespace ROCKSDB_NAMESPACE {
15/**
16 * Customizable a base class used by the rocksdb that describes a
17 * standard way of configuring and creating objects. Customizable objects
18 * are configurable objects that can be created from an ObjectRegistry.
19 *
20 * Customizable classes are used when there are multiple potential
21 * implementations of a class for use by RocksDB (e.g. Table, Cache,
22 * MergeOperator, etc). The abstract base class is expected to define a method
23 * declaring its type and a factory method for creating one of these, such as:
24 * static const char *Type() { return "Table"; }
25 * static Status CreateFromString(const ConfigOptions& options,
26 * const std::string& id,
27 * std::shared_ptr<TableFactory>* result);
28 * The "Type" string is expected to be unique (no two base classes are the same
29 * type). This factory is expected, based on the options and id, create and
30 * return the appropriate derived type of the customizable class (e.g.
31 * BlockBasedTableFactory, PlainTableFactory, etc). For extension developers,
32 * helper classes and methods are provided for writing this factory.
33 *
34 * Instances of a Customizable class need to define:
35 * - A "static const char *kClassName()" method. This method defines the name
36 * of the class instance (e.g. BlockBasedTable, LRUCache) and is used by the
37 * CheckedCast method.
38 * - The Name() of the object. This name is used when creating and saving
39 * instances of this class. Typically this name will be the same as
40 * kClassName().
41 *
42 * Additionally, Customizable classes should register any options used to
43 * configure themselves with the Configurable subsystem.
44 *
45 * When a Customizable is being created, the "name" property specifies
46 * the name of the instance being created.
47 * For custom objects, their configuration and name can be specified by:
48 * [prop]={name=X;option 1 = value1[; option2=value2...]}
49 *
50 * [prop].name=X
51 * [prop].option1 = value1
52 *
53 * [prop].name=X
54 * X.option1 =value1
55 */
56class Customizable : public Configurable {
57 public:
1e59de90 58 ~Customizable() override {}
20effc67
TL
59
60 // Returns the name of this class of Customizable
61 virtual const char* Name() const = 0;
62
63 // Returns an identifier for this Customizable.
64 // This could be its name or something more complex (like its URL/pattern).
65 // Used for pretty printing.
66 virtual std::string GetId() const {
67 std::string id = Name();
68 return id;
69 }
70
71 // This is typically determined by if the input name matches the
72 // name of this object.
73 // This method is typically used in conjunction with CheckedCast to find the
74 // derived class instance from its base. For example, if you have an Env
75 // and want the "Default" env, you would IsInstanceOf("Default") to get
76 // the default implementation. This method should be used when you need a
77 // specific derivative or implementation of a class.
78 //
79 // Intermediary caches (such as SharedCache) may wish to override this method
80 // to check for the intermediary name (SharedCache). Classes with multiple
81 // potential names (e.g. "PosixEnv", "DefaultEnv") may also wish to override
82 // this method.
83 //
1e59de90
TL
84 // Note that IsInstanceOf only uses the "is-a" relationship and not "has-a".
85 // Wrapped classes that have an Inner "has-a" should not be returned.
86 //
20effc67
TL
87 // @param name The name of the instance to find.
88 // Returns true if the class is an instance of the input name.
89 virtual bool IsInstanceOf(const std::string& name) const {
1e59de90
TL
90 if (name.empty()) {
91 return false;
92 } else if (name == Name()) {
93 return true;
94 } else {
95 const char* nickname = NickName();
96 if (nickname != nullptr && name == nickname) {
97 return true;
98 } else {
99 return false;
100 }
101 }
102 }
103
104 const void* GetOptionsPtr(const std::string& name) const override {
105 const void* ptr = Configurable::GetOptionsPtr(name);
106 if (ptr != nullptr) {
107 return ptr;
108 } else {
109 const auto inner = Inner();
110 if (inner != nullptr) {
111 return inner->GetOptionsPtr(name);
112 } else {
113 return nullptr;
114 }
115 }
20effc67
TL
116 }
117
118 // Returns the named instance of the Customizable as a T*, or nullptr if not
1e59de90
TL
119 // found. This method uses IsInstanceOf/Inner to find the appropriate class
120 // instance and then casts it to the expected return type.
20effc67
TL
121 template <typename T>
122 const T* CheckedCast() const {
123 if (IsInstanceOf(T::kClassName())) {
124 return static_cast<const T*>(this);
125 } else {
1e59de90
TL
126 const auto inner = Inner();
127 if (inner != nullptr) {
128 return inner->CheckedCast<T>();
129 } else {
130 return nullptr;
131 }
20effc67
TL
132 }
133 }
134
135 template <typename T>
136 T* CheckedCast() {
137 if (IsInstanceOf(T::kClassName())) {
138 return static_cast<T*>(this);
139 } else {
1e59de90
TL
140 auto inner = const_cast<Customizable*>(Inner());
141 if (inner != nullptr) {
142 return inner->CheckedCast<T>();
143 } else {
144 return nullptr;
145 }
20effc67
TL
146 }
147 }
148
149 // Checks to see if this Customizable is equivalent to other.
150 // This method assumes that the two objects are of the same class.
151 // @param config_options Controls how the options are compared.
152 // @param other The other object to compare to.
153 // @param mismatch If the objects do not match, this parameter contains
154 // the name of the option that triggered the match failure.
155 // @param True if the objects match, false otherwise.
156 // @see Configurable::AreEquivalent for more details
157 bool AreEquivalent(const ConfigOptions& config_options,
158 const Configurable* other,
159 std::string* mismatch) const override;
160#ifndef ROCKSDB_LITE
161 // Gets the value of the option associated with the input name
162 // @see Configurable::GetOption for more details
163 Status GetOption(const ConfigOptions& config_options, const std::string& name,
164 std::string* value) const override;
20effc67 165#endif // ROCKSDB_LITE
1e59de90
TL
166 // Helper method for getting for parsing the opt_value into the corresponding
167 // options for use in potentially creating a new Customizable object (this
168 // method is primarily a support method for LoadSharedObject et al for new
169 // Customizable objects). The opt_value may be either name-value pairs
170 // separated by ";" (a=b; c=d), or a simple name (a). In order to create a new
171 // Customizable, the ID is determined by:
172 // - If the value is a simple name (e.g. "BlockBasedTable"), the id is this
173 // name;
174 // - Otherwise, if there is a "id=value", the id is set to "value"
175 // - Otherwise, if the input customizable is not null, custom->GetId is used
176 // - Otherwise, an error is returned.
177 //
178 // If the opt_value is name-value pairs, these pairs will be returned in
179 // options (without the id pair). If the ID being returned matches the ID of
180 // the input custom object, then the options from the input object will also
181 // be added to the returned options.
182 //
183 // This method returns non-OK if the ID could not be found, or if the
184 // opt_value could not be parsed into name-value pairs.
185 static Status GetOptionsMap(
186 const ConfigOptions& config_options, const Customizable* custom,
187 const std::string& opt_value, std::string* id,
188 std::unordered_map<std::string, std::string>* options);
189
190 // Helper method to configure a new object with the supplied options.
191 // If the object is not null and invoke_prepare_options=true, the object
192 // will be configured and prepared.
193 // Returns success if the object is properly configured and (optionally)
194 // prepared Returns InvalidArgument if the object is nullptr and there are
195 // options in the map Returns the result of the ConfigureFromMap or
196 // PrepareOptions
197 static Status ConfigureNewObject(
198 const ConfigOptions& config_options, Customizable* object,
199 const std::unordered_map<std::string, std::string>& options);
200
201 // Returns the inner class when a Customizable implements a has-a (wrapped)
202 // relationship. Derived classes that implement a has-a must override this
203 // method in order to get CheckedCast to function properly.
204 virtual const Customizable* Inner() const { return nullptr; }
205
20effc67 206 protected:
1e59de90
TL
207 // Generates a ID specific for this instance of the customizable.
208 // The unique ID is of the form <name>:<addr>#pid, where:
209 // - name is the Name() of this object;
210 // - addr is the memory address of this object;
211 // - pid is the process ID of this process ID for this process.
212 // Note that if obj1 and obj2 have the same unique IDs, they must be the
213 // same. However, if an object is deleted and recreated, it may have the
214 // same unique ID as a predecessor
215 //
216 // This method is useful for objects (especially ManagedObjects) that
217 // wish to generate an ID that is specific for this instance and wish to
218 // override the GetId() method.
219 std::string GenerateIndividualId() const;
220
221 // Some classes have both a class name (e.g. PutOperator) and a nickname
222 // (e.g. put). Classes can override this method to return a
223 // nickname. Nicknames can be used by InstanceOf and object creation.
224 virtual const char* NickName() const { return ""; }
20effc67
TL
225 // Given a name (e.g. rocksdb.my.type.opt), returns the short name (opt)
226 std::string GetOptionName(const std::string& long_name) const override;
227#ifndef ROCKSDB_LITE
228 std::string SerializeOptions(const ConfigOptions& options,
229 const std::string& prefix) const override;
230#endif // ROCKSDB_LITE
231};
232
233} // namespace ROCKSDB_NAMESPACE