diff --git a/db/compaction/compaction_job.h b/db/compaction/compaction_job.h index c519b59590..82397a8210 100644 --- a/db/compaction/compaction_job.h +++ b/db/compaction/compaction_job.h @@ -434,7 +434,7 @@ struct CompactionServiceOutputFile { uint64_t _epoch_number, const std::string& _file_checksum, const std::string& _file_checksum_func_name, uint64_t _paranoid_hash, bool _marked_for_compaction, UniqueId64x2 _unique_id, - const std::shared_ptr& _table_properties) + const TableProperties& _table_properties) : file_name(name), smallest_seqno(smallest), largest_seqno(largest), @@ -448,7 +448,7 @@ struct CompactionServiceOutputFile { paranoid_hash(_paranoid_hash), marked_for_compaction(_marked_for_compaction), unique_id(std::move(_unique_id)), - table_properties(*_table_properties.get()) {} + table_properties(_table_properties) {} }; // CompactionServiceResult contains the compaction result from a different db diff --git a/db/compaction/compaction_job_test.cc b/db/compaction/compaction_job_test.cc index cf981cc95a..94ad1e2905 100644 --- a/db/compaction/compaction_job_test.cc +++ b/db/compaction/compaction_job_test.cc @@ -1672,9 +1672,6 @@ TEST_F(CompactionJobTest, ResultSerialization) { tp.readable_properties.emplace("RP_K2y2", rnd.RandomString(rnd.Uniform(kStrMaxLen))); - std::shared_ptr table_properties = - std::make_shared(tp); - UniqueId64x2 id{rnd64.Uniform(UINT64_MAX), rnd64.Uniform(UINT64_MAX)}; result.output_files.emplace_back( rnd.RandomString(rnd.Uniform(kStrMaxLen)) /* file_name */, @@ -1690,8 +1687,7 @@ TEST_F(CompactionJobTest, ResultSerialization) { file_checksum /* file_checksum */, file_checksum_func_name /* file_checksum_func_name */, rnd64.Uniform(UINT64_MAX) /* paranoid_hash */, - rnd.OneIn(2) /* marked_for_compaction */, id /* unique_id */, - table_properties); + rnd.OneIn(2) /* marked_for_compaction */, id /* unique_id */, tp); } result.output_level = rnd.Uniform(10); result.output_path = rnd.RandomString(rnd.Uniform(kStrMaxLen)); diff --git a/db/compaction/compaction_service_job.cc b/db/compaction/compaction_service_job.cc index ff6dd91822..949ca19eb7 100644 --- a/db/compaction/compaction_service_job.cc +++ b/db/compaction/compaction_service_job.cc @@ -385,7 +385,7 @@ Status CompactionServiceCompactionJob::Run() { meta.file_creation_time, meta.epoch_number, meta.file_checksum, meta.file_checksum_func_name, output_file.validator.GetHash(), meta.marked_for_compaction, meta.unique_id, - output_file.table_properties); + *output_file.table_properties); } TEST_SYNC_POINT_CALLBACK("CompactionServiceCompactionJob::Run:0", @@ -477,159 +477,6 @@ static std::unordered_map cs_input_type_info = { OptionType::kUInt64T, OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, }; -static std::unordered_map - table_properties_type_info = { - {"orig_file_number", - {offsetof(struct TableProperties, orig_file_number), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"data_size", - {offsetof(struct TableProperties, data_size), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"index_size", - {offsetof(struct TableProperties, index_size), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"index_partitions", - {offsetof(struct TableProperties, index_partitions), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"top_level_index_size", - {offsetof(struct TableProperties, top_level_index_size), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"index_key_is_user_key", - {offsetof(struct TableProperties, index_key_is_user_key), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"index_value_is_delta_encoded", - {offsetof(struct TableProperties, index_value_is_delta_encoded), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"filter_size", - {offsetof(struct TableProperties, filter_size), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"raw_key_size", - {offsetof(struct TableProperties, raw_key_size), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"raw_value_size", - {offsetof(struct TableProperties, raw_value_size), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"num_data_blocks", - {offsetof(struct TableProperties, num_data_blocks), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"num_entries", - {offsetof(struct TableProperties, num_entries), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"num_filter_entries", - {offsetof(struct TableProperties, num_filter_entries), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"num_deletions", - {offsetof(struct TableProperties, num_deletions), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"num_merge_operands", - {offsetof(struct TableProperties, num_merge_operands), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"num_range_deletions", - {offsetof(struct TableProperties, num_range_deletions), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"format_version", - {offsetof(struct TableProperties, format_version), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"fixed_key_len", - {offsetof(struct TableProperties, fixed_key_len), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"column_family_id", - {offsetof(struct TableProperties, column_family_id), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"creation_time", - {offsetof(struct TableProperties, creation_time), OptionType::kUInt64T, - OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, - {"oldest_key_time", - {offsetof(struct TableProperties, oldest_key_time), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"file_creation_time", - {offsetof(struct TableProperties, file_creation_time), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"slow_compression_estimated_data_size", - {offsetof(struct TableProperties, - slow_compression_estimated_data_size), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"fast_compression_estimated_data_size", - {offsetof(struct TableProperties, - fast_compression_estimated_data_size), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"external_sst_file_global_seqno_offset", - {offsetof(struct TableProperties, - external_sst_file_global_seqno_offset), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"tail_start_offset", - {offsetof(struct TableProperties, tail_start_offset), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"user_defined_timestamps_persisted", - {offsetof(struct TableProperties, user_defined_timestamps_persisted), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"key_largest_seqno", - {offsetof(struct TableProperties, key_largest_seqno), - OptionType::kUInt64T, OptionVerificationType::kNormal, - OptionTypeFlags::kNone}}, - {"db_id", - {offsetof(struct TableProperties, db_id), OptionType::kEncodedString}}, - {"db_session_id", - {offsetof(struct TableProperties, db_session_id), - OptionType::kEncodedString}}, - {"db_host_id", - {offsetof(struct TableProperties, db_host_id), - OptionType::kEncodedString}}, - {"column_family_name", - {offsetof(struct TableProperties, column_family_name), - OptionType::kEncodedString}}, - {"filter_policy_name", - {offsetof(struct TableProperties, filter_policy_name), - OptionType::kEncodedString}}, - {"comparator_name", - {offsetof(struct TableProperties, comparator_name), - OptionType::kEncodedString}}, - {"merge_operator_name", - {offsetof(struct TableProperties, merge_operator_name), - OptionType::kEncodedString}}, - {"prefix_extractor_name", - {offsetof(struct TableProperties, prefix_extractor_name), - OptionType::kEncodedString}}, - {"property_collectors_names", - {offsetof(struct TableProperties, property_collectors_names), - OptionType::kEncodedString}}, - {"compression_name", - {offsetof(struct TableProperties, compression_name), - OptionType::kEncodedString}}, - {"compression_options", - {offsetof(struct TableProperties, compression_options), - OptionType::kEncodedString}}, - {"seqno_to_time_mapping", - {offsetof(struct TableProperties, seqno_to_time_mapping), - OptionType::kEncodedString}}, - {"user_collected_properties", - OptionTypeInfo::StringMap( - offsetof(struct TableProperties, user_collected_properties), - OptionVerificationType::kNormal, OptionTypeFlags::kNone)}, - {"readable_properties", - OptionTypeInfo::StringMap( - offsetof(struct TableProperties, readable_properties), - OptionVerificationType::kNormal, OptionTypeFlags::kNone)}, -}; static std::unordered_map cs_output_file_type_info = { @@ -687,11 +534,29 @@ static std::unordered_map OptionVerificationType::kNormal, OptionTypeFlags::kNone, {0, OptionType::kUInt64T})}, {"table_properties", - OptionTypeInfo::Struct( - "table_properties", &table_properties_type_info, - offsetof(struct CompactionServiceOutputFile, table_properties), - OptionVerificationType::kNormal, OptionTypeFlags::kNone)}, -}; + {offsetof(struct CompactionServiceOutputFile, table_properties), + OptionType::kStruct, OptionVerificationType::kNormal, + OptionTypeFlags::kNone, + [](const ConfigOptions& opts, const std::string& /*name*/, + const std::string& value, void* addr) { + auto table_properties = static_cast(addr); + return TableProperties::Parse(opts, value, table_properties); + }, + [](const ConfigOptions& opts, const std::string& /*name*/, + const void* addr, std::string* value) { + const auto table_properties = + static_cast(addr); + std::string result; + auto status = table_properties->Serialize(opts, &result); + *value = "{" + result + "}"; + return status; + }, + [](const ConfigOptions& opts, const std::string& /*name*/, + const void* addr1, const void* addr2, std::string* mismatch) { + const auto this_one = static_cast(addr1); + const auto that_one = static_cast(addr2); + return this_one->AreEqual(opts, that_one, mismatch); + }}}}; static std::unordered_map compaction_job_stats_type_info = { diff --git a/include/rocksdb/table_properties.h b/include/rocksdb/table_properties.h index f247d339aa..84677a4d2d 100644 --- a/include/rocksdb/table_properties.h +++ b/include/rocksdb/table_properties.h @@ -371,6 +371,14 @@ struct TableProperties { // Return the approximated memory usage of this TableProperties object, // including memory used by the string properties and UserCollectedProperties std::size_t ApproximateMemoryUsage() const; + + // Serialize and deserialize Table Properties + Status Serialize(const ConfigOptions& opts, std::string* output) const; + static Status Parse(const ConfigOptions& opts, const std::string& serialized, + TableProperties* table_properties); + bool AreEqual(const ConfigOptions& opts, + const TableProperties* other_table_properties, + std::string* mismatch) const; }; // Extra properties diff --git a/options/options_settable_test.cc b/options/options_settable_test.cc index 80021444fc..1a86fb26ed 100644 --- a/options/options_settable_test.cc +++ b/options/options_settable_test.cc @@ -218,6 +218,94 @@ TEST_F(OptionsSettableTest, BlockBasedTableOptionsAllFieldsSettable) { delete[] new_bbto_ptr; } +TEST_F(OptionsSettableTest, TablePropertiesAllFieldsSettable) { + const OffsetGap kTablePropertiesExcluded = { + {offsetof(struct TableProperties, db_id), sizeof(std::string)}, + {offsetof(struct TableProperties, db_session_id), sizeof(std::string)}, + {offsetof(struct TableProperties, db_host_id), sizeof(std::string)}, + {offsetof(struct TableProperties, column_family_name), + sizeof(std::string)}, + {offsetof(struct TableProperties, filter_policy_name), + sizeof(std::string)}, + {offsetof(struct TableProperties, comparator_name), sizeof(std::string)}, + {offsetof(struct TableProperties, merge_operator_name), + sizeof(std::string)}, + {offsetof(struct TableProperties, prefix_extractor_name), + sizeof(std::string)}, + {offsetof(struct TableProperties, property_collectors_names), + sizeof(std::string)}, + {offsetof(struct TableProperties, compression_name), sizeof(std::string)}, + {offsetof(struct TableProperties, compression_options), + sizeof(std::string)}, + {offsetof(struct TableProperties, seqno_to_time_mapping), + sizeof(std::string)}, + {offsetof(struct TableProperties, user_collected_properties), + sizeof(UserCollectedProperties)}, + {offsetof(struct TableProperties, readable_properties), + sizeof(UserCollectedProperties)}, + }; + + char* tp_ptr = new char[sizeof(TableProperties)]; + + TableProperties* tp = new (tp_ptr) TableProperties(); + FillWithSpecialChar(tp_ptr, sizeof(TableProperties), + kTablePropertiesExcluded); + ASSERT_GT( + NumUnsetBytes(tp_ptr, sizeof(TableProperties), kTablePropertiesExcluded), + 0); + + char* new_tp_ptr = new char[sizeof(TableProperties)]; + TableProperties* new_tp = new (new_tp_ptr) TableProperties(); + FillWithSpecialChar(new_tp_ptr, sizeof(TableProperties), + kTablePropertiesExcluded); + + // Need to update the option string if a new option is added. + ConfigOptions config_options; + config_options.input_strings_escaped = false; + config_options.ignore_unknown_options = false; + config_options.invoke_prepare_options = false; + config_options.ignore_unsupported_options = false; + ASSERT_OK(TableProperties::Parse( + config_options, + "readable_properties={7265616461626C655F6B6579=" + "7265616461626C655F76616C7565;};compression_options=;compression_name=;" + "property_collectors_names=;prefix_extractor_name=;db_host_id=" + "64625F686F73745F6964;db_session_id=64625F73657373696F6E5F6964;creation_" + "time=0;num_data_blocks=123;index_value_is_delta_encoded=0;top_level_" + "index_" + "size=0;data_size=100;merge_operator_name=;index_partitions=0;file_" + "creation_time=0;raw_value_size=0;index_size=200;user_collected_" + "properties={757365725F6B6579=757365725F76616C7565;};tail_start_offset=0;" + "seqno_to_time_mapping=;raw_key_size=0;slow_compression_estimated_data_" + "size=0;filter_size=0;orig_file_number=3;num_deletions=0;num_range_" + "deletions=0;format_version=0;comparator_name=" + "636F6D70617261746F725F6E616D65;num_filter_entries=0;db_id=" + "64625F686F73745F6964;column_family_id=2147483647;fixed_key_len=0;fast_" + "compression_estimated_data_size=0;filter_policy_name=" + "66696C7465725F706F6C6963795F6E616D65;oldest_key_time=0;column_family_" + "name=64656661756C74;user_defined_timestamps_persisted=1;num_entries=100;" + "external_sst_file_global_seqno_offset=0;num_merge_operands=0;index_key_" + "is_user_key=0;key_largest_seqno=18446744073709551615;", + new_tp)); + + // All bytes are set from the parse + ASSERT_EQ(NumUnsetBytes(new_tp_ptr, sizeof(TableProperties), + kTablePropertiesExcluded), + 0); + + ASSERT_EQ(new_tp->db_host_id, "db_host_id"); + ASSERT_EQ(new_tp->num_entries, 100); + ASSERT_EQ(new_tp->num_data_blocks, 123); + ASSERT_EQ(new_tp->user_collected_properties.size(), 1); + ASSERT_EQ(new_tp->readable_properties.size(), 1); + + tp->~TableProperties(); + new_tp->~TableProperties(); + + delete[] tp_ptr; + delete[] new_tp_ptr; +} + // If the test fails, likely a new option is added to DBOptions // but it cannot be set through GetDBOptionsFromString(), or the test is not // updated accordingly. diff --git a/table/table_properties.cc b/table/table_properties.cc index 037e483f6d..e0aff583f3 100644 --- a/table/table_properties.cc +++ b/table/table_properties.cc @@ -10,6 +10,7 @@ #include "port/port.h" #include "rocksdb/env.h" #include "rocksdb/unique_id.h" +#include "rocksdb/utilities/options_type.h" #include "table/table_properties_internal.h" #include "table/unique_id_impl.h" #include "util/random.h" @@ -316,6 +317,178 @@ const std::string TablePropertiesNames::kUserDefinedTimestampsPersisted = const std::string TablePropertiesNames::kKeyLargestSeqno = "rocksdb.key.largest.seqno"; +static std::unordered_map + table_properties_type_info = { + {"orig_file_number", + {offsetof(struct TableProperties, orig_file_number), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"data_size", + {offsetof(struct TableProperties, data_size), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"index_size", + {offsetof(struct TableProperties, index_size), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"index_partitions", + {offsetof(struct TableProperties, index_partitions), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"top_level_index_size", + {offsetof(struct TableProperties, top_level_index_size), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"index_key_is_user_key", + {offsetof(struct TableProperties, index_key_is_user_key), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"index_value_is_delta_encoded", + {offsetof(struct TableProperties, index_value_is_delta_encoded), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"filter_size", + {offsetof(struct TableProperties, filter_size), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"raw_key_size", + {offsetof(struct TableProperties, raw_key_size), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"raw_value_size", + {offsetof(struct TableProperties, raw_value_size), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"num_data_blocks", + {offsetof(struct TableProperties, num_data_blocks), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"num_entries", + {offsetof(struct TableProperties, num_entries), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"num_filter_entries", + {offsetof(struct TableProperties, num_filter_entries), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"num_deletions", + {offsetof(struct TableProperties, num_deletions), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"num_merge_operands", + {offsetof(struct TableProperties, num_merge_operands), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"num_range_deletions", + {offsetof(struct TableProperties, num_range_deletions), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"format_version", + {offsetof(struct TableProperties, format_version), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"fixed_key_len", + {offsetof(struct TableProperties, fixed_key_len), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"column_family_id", + {offsetof(struct TableProperties, column_family_id), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"creation_time", + {offsetof(struct TableProperties, creation_time), OptionType::kUInt64T, + OptionVerificationType::kNormal, OptionTypeFlags::kNone}}, + {"oldest_key_time", + {offsetof(struct TableProperties, oldest_key_time), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"file_creation_time", + {offsetof(struct TableProperties, file_creation_time), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"slow_compression_estimated_data_size", + {offsetof(struct TableProperties, + slow_compression_estimated_data_size), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"fast_compression_estimated_data_size", + {offsetof(struct TableProperties, + fast_compression_estimated_data_size), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"external_sst_file_global_seqno_offset", + {offsetof(struct TableProperties, + external_sst_file_global_seqno_offset), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"tail_start_offset", + {offsetof(struct TableProperties, tail_start_offset), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"user_defined_timestamps_persisted", + {offsetof(struct TableProperties, user_defined_timestamps_persisted), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"key_largest_seqno", + {offsetof(struct TableProperties, key_largest_seqno), + OptionType::kUInt64T, OptionVerificationType::kNormal, + OptionTypeFlags::kNone}}, + {"db_id", + {offsetof(struct TableProperties, db_id), OptionType::kEncodedString}}, + {"db_session_id", + {offsetof(struct TableProperties, db_session_id), + OptionType::kEncodedString}}, + {"db_host_id", + {offsetof(struct TableProperties, db_host_id), + OptionType::kEncodedString}}, + {"column_family_name", + {offsetof(struct TableProperties, column_family_name), + OptionType::kEncodedString}}, + {"filter_policy_name", + {offsetof(struct TableProperties, filter_policy_name), + OptionType::kEncodedString}}, + {"comparator_name", + {offsetof(struct TableProperties, comparator_name), + OptionType::kEncodedString}}, + {"merge_operator_name", + {offsetof(struct TableProperties, merge_operator_name), + OptionType::kEncodedString}}, + {"prefix_extractor_name", + {offsetof(struct TableProperties, prefix_extractor_name), + OptionType::kEncodedString}}, + {"property_collectors_names", + {offsetof(struct TableProperties, property_collectors_names), + OptionType::kEncodedString}}, + {"compression_name", + {offsetof(struct TableProperties, compression_name), + OptionType::kEncodedString}}, + {"compression_options", + {offsetof(struct TableProperties, compression_options), + OptionType::kEncodedString}}, + {"seqno_to_time_mapping", + {offsetof(struct TableProperties, seqno_to_time_mapping), + OptionType::kEncodedString}}, + {"user_collected_properties", + OptionTypeInfo::StringMap( + offsetof(struct TableProperties, user_collected_properties), + OptionVerificationType::kNormal, OptionTypeFlags::kNone)}, + {"readable_properties", + OptionTypeInfo::StringMap( + offsetof(struct TableProperties, readable_properties), + OptionVerificationType::kNormal, OptionTypeFlags::kNone)}, +}; + +Status TableProperties::Serialize(const ConfigOptions& opts, + std::string* output) const { + return OptionTypeInfo::SerializeType(opts, table_properties_type_info, this, + output); +} +Status TableProperties::Parse(const ConfigOptions& opts, + const std::string& serialized, + TableProperties* table_properties) { + return OptionTypeInfo::ParseType(opts, serialized, table_properties_type_info, + table_properties); +} +bool TableProperties::AreEqual(const ConfigOptions& opts, + const TableProperties* other_table_properties, + std::string* mismatch) const { + return OptionTypeInfo::TypesAreEqual(opts, table_properties_type_info, this, + other_table_properties, mismatch); +} + #ifndef NDEBUG // WARNING: TEST_SetRandomTableProperties assumes the following layout of // TableProperties