/src/rocksdb/options/customizable.cc
Line | Count | Source |
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 | | |
6 | | #include "rocksdb/customizable.h" |
7 | | |
8 | | #include <sstream> |
9 | | |
10 | | #include "options/options_helper.h" |
11 | | #include "port/port.h" |
12 | | #include "rocksdb/convenience.h" |
13 | | #include "rocksdb/status.h" |
14 | | #include "rocksdb/utilities/options_type.h" |
15 | | #include "util/string_util.h" |
16 | | |
17 | | namespace ROCKSDB_NAMESPACE { |
18 | | |
19 | 3.94M | std::string Customizable::GetOptionName(const std::string& long_name) const { |
20 | 3.94M | const std::string& name = Name(); |
21 | 3.94M | size_t name_len = name.size(); |
22 | 3.94M | if (long_name.size() > name_len + 1 && |
23 | 3.15M | long_name.compare(0, name_len, name) == 0 && |
24 | 0 | long_name.at(name_len) == '.') { |
25 | 0 | return long_name.substr(name_len + 1); |
26 | 3.94M | } else { |
27 | 3.94M | return Configurable::GetOptionName(long_name); |
28 | 3.94M | } |
29 | 3.94M | } |
30 | | |
31 | 0 | std::string Customizable::GenerateIndividualId() const { |
32 | 0 | std::ostringstream ostr; |
33 | 0 | ostr << Name() << "@" << static_cast<const void*>(this) << "#" |
34 | 0 | << port::GetProcessID(); |
35 | 0 | return ostr.str(); |
36 | 0 | } |
37 | | |
38 | | Status Customizable::GetOption(const ConfigOptions& config_options, |
39 | | const std::string& opt_name, |
40 | 0 | std::string* value) const { |
41 | 0 | if (opt_name == OptionTypeInfo::kIdPropName()) { |
42 | 0 | *value = GetId(); |
43 | 0 | return Status::OK(); |
44 | 0 | } else { |
45 | 0 | return Configurable::GetOption(config_options, opt_name, value); |
46 | 0 | } |
47 | 0 | } |
48 | | |
49 | | std::string Customizable::SerializeOptions(const ConfigOptions& config_options, |
50 | 789k | const std::string& prefix) const { |
51 | 789k | std::string result; |
52 | 789k | std::string parent; |
53 | 789k | std::string id = GetId(); |
54 | 789k | if (!config_options.IsShallow() && !id.empty()) { |
55 | 789k | parent = Configurable::SerializeOptions(config_options, ""); |
56 | 789k | } |
57 | 789k | if (parent.empty()) { |
58 | 690k | result = id; |
59 | 690k | } else { |
60 | 98.6k | result.append(prefix); |
61 | 98.6k | result.append(OptionTypeInfo::kIdPropName()); |
62 | 98.6k | result.append("="); |
63 | 98.6k | result.append(id); |
64 | 98.6k | result.append(config_options.delimiter); |
65 | 98.6k | result.append(parent); |
66 | 98.6k | } |
67 | 789k | return result; |
68 | 789k | } |
69 | | |
70 | | bool Customizable::AreEquivalent(const ConfigOptions& config_options, |
71 | | const Configurable* other, |
72 | 295k | std::string* mismatch) const { |
73 | 295k | if (config_options.sanity_level > ConfigOptions::kSanityLevelNone && |
74 | 295k | this != other) { |
75 | 295k | const Customizable* custom = static_cast<const Customizable*>(other); |
76 | 295k | if (custom == nullptr) { // Cast failed |
77 | 0 | return false; |
78 | 295k | } else if (GetId() != custom->GetId()) { |
79 | 0 | *mismatch = OptionTypeInfo::kIdPropName(); |
80 | 0 | return false; |
81 | 295k | } else if (config_options.sanity_level > |
82 | 295k | ConfigOptions::kSanityLevelLooselyCompatible) { |
83 | 197k | bool matches = |
84 | 197k | Configurable::AreEquivalent(config_options, other, mismatch); |
85 | 197k | return matches; |
86 | 197k | } |
87 | 295k | } |
88 | 98.6k | return true; |
89 | 295k | } |
90 | | |
91 | | Status Customizable::GetOptionsMap( |
92 | | const ConfigOptions& config_options, const Customizable* customizable, |
93 | | const std::string& value, std::string* id, |
94 | 1.40M | std::unordered_map<std::string, std::string>* props) { |
95 | 1.40M | Status status; |
96 | 1.40M | if (value.empty() || value == kNullptrString) { |
97 | 907k | *id = ""; |
98 | 907k | props->clear(); |
99 | 907k | } else if (customizable != nullptr) { |
100 | 197k | status = |
101 | 197k | Configurable::GetOptionsMap(value, customizable->GetId(), id, props); |
102 | 197k | if (status.ok() && customizable->IsInstanceOf(*id)) { |
103 | | // The new ID and the old ID match, so the objects are the same type. |
104 | | // Try to get the existing options, ignoring any errors |
105 | 197k | ConfigOptions embedded = config_options; |
106 | 197k | embedded.delimiter = ";"; |
107 | 197k | std::string curr_opts; |
108 | 197k | if (customizable->GetOptionString(embedded, &curr_opts).ok()) { |
109 | 197k | std::unordered_map<std::string, std::string> curr_props; |
110 | 197k | if (StringToMap(curr_opts, &curr_props).ok()) { |
111 | 197k | props->insert(curr_props.begin(), curr_props.end()); |
112 | 197k | } |
113 | 197k | } |
114 | 197k | } |
115 | 296k | } else { |
116 | 296k | status = Configurable::GetOptionsMap(value, "", id, props); |
117 | 296k | } |
118 | 1.40M | return status; |
119 | 1.40M | } |
120 | | |
121 | | Status Customizable::ConfigureNewObject( |
122 | | const ConfigOptions& config_options, Customizable* object, |
123 | 394k | const std::unordered_map<std::string, std::string>& opt_map) { |
124 | 394k | Status status; |
125 | 394k | if (object != nullptr) { |
126 | 394k | status = object->ConfigureFromMap(config_options, opt_map); |
127 | 394k | } else if (!opt_map.empty()) { |
128 | 0 | status = Status::InvalidArgument("Cannot configure null object "); |
129 | 0 | } |
130 | 394k | return status; |
131 | 394k | } |
132 | | } // namespace ROCKSDB_NAMESPACE |