Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize only options that have changed from the some default #648

Merged
merged 10 commits into from
Oct 31, 2023
20 changes: 16 additions & 4 deletions db/compaction/compaction_service_job.cc
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ static std::unordered_map<std::string, OptionTypeInfo> cs_result_type_info = {
const auto status_obj = static_cast<const Status*>(addr);
StatusSerializationAdapter adapter(*status_obj);
std::string result;
Status s = OptionTypeInfo::SerializeType(opts, status_adapter_type_info,
&adapter, &result);
Status s = OptionTypeInfo::TypeToString(
opts, "", status_adapter_type_info, &adapter, &result);
*value = "{" + result + "}";
return s;
},
Expand Down Expand Up @@ -770,7 +770,13 @@ Status CompactionServiceInput::Write(std::string* output) {
output->append(buf, sizeof(BinaryFormatVersion));
ConfigOptions cf;
cf.invoke_prepare_options = false;
return OptionTypeInfo::SerializeType(cf, cs_input_type_info, this, output);
std::unordered_map<std::string, std::string> options;
Status s =
OptionTypeInfo::SerializeType(cf, cs_input_type_info, this, &options);
if (s.ok()) {
output->append(cf.ToString("", options) + cf.delimiter);
}
return s;
}

Status CompactionServiceResult::Read(const std::string& data_str,
Expand Down Expand Up @@ -799,7 +805,13 @@ Status CompactionServiceResult::Write(std::string* output) {
output->append(buf, sizeof(BinaryFormatVersion));
ConfigOptions cf;
cf.invoke_prepare_options = false;
return OptionTypeInfo::SerializeType(cf, cs_result_type_info, this, output);
std::unordered_map<std::string, std::string> options;
Status s =
OptionTypeInfo::SerializeType(cf, cs_result_type_info, this, &options);
if (s.ok()) {
output->append(cf.ToString("", options) + cf.delimiter);
}
return s;
}

#ifndef NDEBUG
Expand Down
37 changes: 13 additions & 24 deletions env/composite_env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ Status CompositeEnv::NewDirectory(const std::string& name,

namespace {
static std::unordered_map<std::string, OptionTypeInfo> env_wrapper_type_info = {
{"target",
{Customizable::kTargetPropName(),
OptionTypeInfo(0, OptionType::kUnknown, OptionVerificationType::kByName,
OptionTypeFlags::kDontSerialize)
.SetParseFunc([](const ConfigOptions& opts,
Expand Down Expand Up @@ -482,14 +482,13 @@ Status CompositeEnvWrapper::PrepareOptions(const ConfigOptions& options) {
return Env::PrepareOptions(options);
}

std::string CompositeEnvWrapper::SerializeOptions(
const ConfigOptions& config_options, const std::string& header) const {
auto options = CompositeEnv::SerializeOptions(config_options, header);
Status CompositeEnvWrapper::SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const {
if (target_.env != nullptr && target_.env != Env::Default()) {
options.append("target=");
options.append(target_.env->ToString(config_options));
options->insert({kTargetPropName(), target_.env->ToString(config_options)});
}
return options;
return CompositeEnv::SerializeOptions(config_options, options);
}

EnvWrapper::EnvWrapper(Env* t) : target_(t) {
Expand All @@ -511,24 +510,14 @@ Status EnvWrapper::PrepareOptions(const ConfigOptions& options) {
return Env::PrepareOptions(options);
}

std::string EnvWrapper::SerializeOptions(const ConfigOptions& config_options,
const std::string& header) const {
auto parent = Env::SerializeOptions(config_options, "");
if (config_options.IsShallow() || target_.env == nullptr ||
target_.env == Env::Default()) {
return parent;
} else {
std::string result = header;
if (!StartsWith(parent, OptionTypeInfo::kIdPropName())) {
result.append(OptionTypeInfo::kIdPropName()).append("=");
}
result.append(parent);
if (!EndsWith(result, config_options.delimiter)) {
result.append(config_options.delimiter);
}
result.append("target=").append(target_.env->ToString(config_options));
return result;
Status EnvWrapper::SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const {
if (!config_options.IsShallow() && target_.env != nullptr &&
target_.env != Env::Default()) {
options->insert({kTargetPropName(), target_.env->ToString(config_options)});
}
return Env::SerializeOptions(config_options, options);
}

} // namespace ROCKSDB_NAMESPACE
5 changes: 3 additions & 2 deletions env/composite_env_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,9 @@ class CompositeEnvWrapper : public CompositeEnv {
const Customizable* Inner() const override { return target_.env; }

Status PrepareOptions(const ConfigOptions& options) override;
std::string SerializeOptions(const ConfigOptions& config_options,
const std::string& header) const override;
Status SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const override;

// Return the target to which this Env forwards all calls
Env* env_target() const { return target_.env; }
Expand Down
44 changes: 20 additions & 24 deletions env/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,15 @@ class LegacySystemClock : public SystemClock {
return env_->TimeToString(time);
}

std::string SerializeOptions(const ConfigOptions& /*config_options*/,
const std::string& /*prefix*/) const override {
Status SerializeOptions(
const ConfigOptions& /*config_options*/,
std::unordered_map<std::string, std::string>* /*options*/)
const override {
// We do not want the LegacySystemClock to appear in the serialized output.
// This clock is an internal class for those who do not implement one and
// would be part of the Env. As such, do not serialize it here.
return "";
return Status::OK();
;
}
};

Expand Down Expand Up @@ -599,13 +602,16 @@ class LegacyFileSystemWrapper : public FileSystem {
return status_to_io_status(target_->IsDirectory(path, is_dir));
}

std::string SerializeOptions(const ConfigOptions& /*config_options*/,
const std::string& /*prefix*/) const override {
Status SerializeOptions(
const ConfigOptions& /*config_options*/,
std::unordered_map<std::string, std::string>* /*options*/)
const override {
// We do not want the LegacyFileSystem to appear in the serialized output.
// This clock is an internal class for those who do not implement one and
// would be part of the Env. As such, do not serialize it here.
return "";
return Status::OK();
}

private:
Env* target_;
};
Expand Down Expand Up @@ -1164,7 +1170,7 @@ const std::shared_ptr<SystemClock>& Env::GetSystemClock() const {
}
namespace {
static std::unordered_map<std::string, OptionTypeInfo> sc_wrapper_type_info = {
{"target",
{Customizable::kTargetPropName(),
OptionTypeInfo::AsCustomSharedPtr<SystemClock>(
0, OptionVerificationType::kByName, OptionTypeFlags::kDontSerialize)},
};
Expand All @@ -1182,24 +1188,14 @@ Status SystemClockWrapper::PrepareOptions(const ConfigOptions& options) {
return SystemClock::PrepareOptions(options);
}

std::string SystemClockWrapper::SerializeOptions(
const ConfigOptions& config_options, const std::string& header) const {
auto parent = SystemClock::SerializeOptions(config_options, "");
if (config_options.IsShallow() || target_ == nullptr ||
target_->IsInstanceOf(SystemClock::kDefaultName())) {
return parent;
} else {
std::string result = header;
if (!StartsWith(parent, OptionTypeInfo::kIdPropName())) {
result.append(OptionTypeInfo::kIdPropName()).append("=");
}
result.append(parent);
if (!EndsWith(result, config_options.delimiter)) {
result.append(config_options.delimiter);
}
result.append("target=").append(target_->ToString(config_options));
return result;
Status SystemClockWrapper::SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const {
if (!config_options.IsShallow() && target_ != nullptr &&
!target_->IsInstanceOf(SystemClock::kDefaultName())) {
options->insert({kTargetPropName(), target_->ToString(config_options)});
}
return SystemClock::SerializeOptions(config_options, options);
}

static int RegisterBuiltinSystemClocks(ObjectLibrary& library,
Expand Down
26 changes: 8 additions & 18 deletions env/file_system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ IOStatus ReadFileToString(FileSystem* fs, const std::string& fname,

namespace {
static std::unordered_map<std::string, OptionTypeInfo> fs_wrapper_type_info = {
{"target",
{Customizable::kTargetPropName(),
OptionTypeInfo::AsCustomSharedPtr<FileSystem>(
0, OptionVerificationType::kByName, OptionTypeFlags::kDontSerialize)},
};
Expand All @@ -243,24 +243,14 @@ Status FileSystemWrapper::PrepareOptions(const ConfigOptions& options) {
return FileSystem::PrepareOptions(options);
}

std::string FileSystemWrapper::SerializeOptions(
const ConfigOptions& config_options, const std::string& header) const {
auto parent = FileSystem::SerializeOptions(config_options, "");
if (config_options.IsShallow() || target_ == nullptr ||
target_->IsInstanceOf(FileSystem::kDefaultName())) {
return parent;
} else {
std::string result = header;
if (!StartsWith(parent, OptionTypeInfo::kIdPropName())) {
result.append(OptionTypeInfo::kIdPropName()).append("=");
}
result.append(parent);
if (!EndsWith(result, config_options.delimiter)) {
result.append(config_options.delimiter);
}
result.append("target=").append(target_->ToString(config_options));
return result;
Status FileSystemWrapper::SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const {
if (!config_options.IsShallow() && target_ != nullptr &&
!target_->IsInstanceOf(FileSystem::kDefaultName())) {
options->insert({kTargetPropName(), target_->ToString(config_options)});
}
return FileSystem::SerializeOptions(config_options, options);
}

DirFsyncOptions::DirFsyncOptions() { reason = kDefault; }
Expand Down
5 changes: 3 additions & 2 deletions include/rocksdb/configurable.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,9 @@ class Configurable {
std::string* bad_name) const;
// 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;
virtual Status SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const;

// Given a name (e.g. rocksdb.my.type.opt), returns the short name (opt)
virtual std::string GetOptionName(const std::string& long_name) const;
Expand Down
10 changes: 10 additions & 0 deletions include/rocksdb/convenience.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct ConfigOptions {
// The object registry to use for this options
std::shared_ptr<ObjectRegistry> registry;

// If set, only changes from this reference version will be serialized.
Configurable* compare_to = nullptr;

bool IsShallow() const { return depth == Depth::kDepthShallow; }
bool IsDetailed() const { return depth == Depth::kDepthDetailed; }

Expand All @@ -103,6 +106,13 @@ struct ConfigOptions {
bool IsCheckEnabled(SanityLevel level) const {
return (level > SanityLevel::kSanityLevelNone && level <= sanity_level);
}
// Converts the map of options to a single string representation
std::string ToString(
const std::string& prefix,
const std::unordered_map<std::string, std::string>& options) const;
// Converts the vector options to a single string representation
std::string ToString(char separator,
const std::vector<std::string>& elems) const;
};


Expand Down
7 changes: 5 additions & 2 deletions include/rocksdb/customizable.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class Customizable : public Configurable {
public:
~Customizable() override {}

constexpr static const char* kTargetPropName() { return "target"; }

// Returns the name of this class of Customizable
virtual const char* Name() const = 0;

Expand Down Expand Up @@ -222,8 +224,9 @@ class Customizable : public Configurable {
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;
std::string SerializeOptions(const ConfigOptions& options,
const std::string& prefix) const override;
Status SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const override;
};

} // namespace ROCKSDB_NAMESPACE
5 changes: 3 additions & 2 deletions include/rocksdb/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -1643,8 +1643,9 @@ class EnvWrapper : public Env {
target_.env->SanitizeEnvOptions(env_opts);
}
Status PrepareOptions(const ConfigOptions& options) override;
std::string SerializeOptions(const ConfigOptions& config_options,
const std::string& header) const override;
Status SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const override;

private:
Target target_;
Expand Down
5 changes: 3 additions & 2 deletions include/rocksdb/file_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -1514,8 +1514,9 @@ class FileSystemWrapper : public FileSystem {

const Customizable* Inner() const override { return target_.get(); }
Status PrepareOptions(const ConfigOptions& options) override;
std::string SerializeOptions(const ConfigOptions& config_options,
const std::string& header) const override;
Status SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const override;

virtual IOStatus Poll(std::vector<void*>& io_handles,
size_t min_completions) override {
Expand Down
5 changes: 3 additions & 2 deletions include/rocksdb/system_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ class SystemClockWrapper : public SystemClock {
}

Status PrepareOptions(const ConfigOptions& options) override;
std::string SerializeOptions(const ConfigOptions& config_options,
const std::string& header) const override;
Status SerializeOptions(
const ConfigOptions& config_options,
std::unordered_map<std::string, std::string>* options) const override;
const Customizable* Inner() const override { return target_.get(); }

protected:
Expand Down
46 changes: 20 additions & 26 deletions include/rocksdb/utilities/options_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,12 @@ class OptionTypeInfo {
static Status SerializeType(
const ConfigOptions& config_options,
const std::unordered_map<std::string, OptionTypeInfo>& type_map,
const void* opt_addr, std::string* value);
const void* opt_addr,
std::unordered_map<std::string, std::string>* options);
static Status TypeToString(
const ConfigOptions& config_options, const std::string& opt_name,
const std::unordered_map<std::string, OptionTypeInfo>& type_map,
const void* opt_addr, std::string* result);

// Serializes the input addr according to the map for the struct to value.
// struct_name is the name of the struct option as registered
Expand Down Expand Up @@ -1156,33 +1161,22 @@ Status SerializeVector(const ConfigOptions& config_options,
const OptionTypeInfo& elem_info, char separator,
const std::string& name, const std::vector<T>& vec,
std::string* value) {
std::string result;
ConfigOptions embedded = config_options;
embedded.delimiter = ";";
int printed = 0;
for (const auto& elem : vec) {
std::string elem_str;
Status s = elem_info.Serialize(embedded, name, &elem, &elem_str);
if (!s.ok()) {
return s;
} else if (!elem_str.empty()) {
if (printed++ > 0) {
result += separator;
}
// If the element contains embedded separators, put it inside of brackets
if (elem_str.find(separator) != std::string::npos) {
result += "{" + elem_str + "}";
} else {
result += elem_str;
if (vec.empty()) {
value->clear();
} else {
std::vector<std::string> opt_vec;
ConfigOptions embedded = config_options;
embedded.delimiter = ";";
for (const auto& elem : vec) {
std::string elem_str;
Status s = elem_info.Serialize(embedded, name, &elem, &elem_str);
if (!s.ok()) {
return s;
} else if (!elem_str.empty()) {
opt_vec.emplace_back(elem_str);
}
}
}
if (result.find("=") != std::string::npos) {
*value = "{" + result + "}";
} else if (printed > 1 && result.at(0) == '{') {
*value = "{" + result + "}";
} else {
*value = result;
*value = config_options.ToString(separator, opt_vec);
}
return Status::OK();
}
Expand Down
Loading
Loading