diff --git a/mutation/mutation.cc b/mutation/mutation.cc index 622f55d69e..b7ca1f1489 100644 --- a/mutation/mutation.cc +++ b/mutation/mutation.cc @@ -209,8 +209,7 @@ std::ostream& operator<<(std::ostream& os, const mutation& m) { ++column_iterator; } - fmt::print(os, "token: {}}}, ", dk._token); - os << mutation_partition::printer(s, m.partition()) << "\n}"; + fmt::print(os, "token: {}}}, {}\n}}", dk._token, mutation_partition::printer(s, m.partition())); return os; } diff --git a/mutation/mutation_partition.cc b/mutation/mutation_partition.cc index a60947cbfe..d72f5177b9 100644 --- a/mutation/mutation_partition.cc +++ b/mutation/mutation_partition.cc @@ -1029,77 +1029,84 @@ operator<<(std::ostream& os, const rows_entry::printer& p) { return os; } -std::ostream& -operator<<(std::ostream& os, const mutation_partition::printer& p) { - const auto indent = " "; +auto fmt::formatter::format(const mutation_partition::printer& p, fmt::format_context& ctx) const + -> decltype(ctx.out()) { + constexpr auto indent = " "; + auto out = ctx.out(); auto& mp = p._mutation_partition; - os << "mutation_partition: {\n"; + out = fmt::format_to(out, "mutation_partition: {{\n"); if (mp._tombstone) { - fmt::print(os, "{}tombstone: {},\n", indent, mp._tombstone); + out = fmt::format_to(out, "{}tombstone: {},\n", indent, mp._tombstone); } if (!mp._row_tombstones.empty()) { - fmt::print(os, "{}range_tombstones: {{{}}},\n", indent, fmt::join(prefixed("\n ", mp._row_tombstones), ",")); + out = fmt::format_to(out, "{}range_tombstones: {{{}}},\n", indent, fmt::join(prefixed("\n ", mp._row_tombstones), ",")); } if (!mp.static_row().empty()) { - os << indent << "static_row: {\n"; + out = fmt::format_to(out, "{}static_row: {{\n", indent); const auto& srow = mp.static_row().get(); srow.for_each_cell([&] (column_id& c_id, const atomic_cell_or_collection& cell) { auto& column_def = p._schema.column_at(column_kind::static_column, c_id); - os << indent << indent << "'" << column_def.name_as_text() - << "': " << atomic_cell_or_collection::printer(column_def, cell) << ",\n"; + out = fmt::format_to(out, "{}{}'{}':{},\n", + indent, indent, column_def.name_as_text(), + atomic_cell_or_collection::printer(column_def, cell)); }); - os << indent << "},\n"; + out = fmt::format_to(out, "{}}},\n", indent); } - os << indent << "rows: [\n"; + out = fmt::format_to(out, "{}rows: [\n", indent); for (const auto& re : mp.clustered_rows()) { - os << indent << indent << "{\n"; + out = fmt::format_to(out, "{}{}{{\n", indent, indent); const auto& row = re.row(); - os << indent << indent << indent << "cont: " << re.continuous() << ",\n"; - os << indent << indent << indent << "dummy: " << re.dummy() << ",\n"; + out = fmt::format_to(out, "{}{}{}cont: {},\n", indent, indent, indent, + re.continuous()); + out = fmt::format_to(out, "{}{}{}dummy: {},\n", indent, indent, indent, + re.dummy()); if (!row.marker().is_missing()) { - os << indent << indent << indent << "marker: " << row.marker() << ",\n"; + out = fmt::format_to(out, "{}{}{}marker: {},\n", indent, indent, indent, + row.marker()); } if (row.deleted_at()) { - os << indent << indent << indent << "tombstone: " << row.deleted_at() << ",\n"; + out = fmt::format_to(out, "{}{}{}tombstone: {},\n", indent, indent, indent, + row.deleted_at()); } position_in_partition pip(re.position()); if (pip.get_clustering_key_prefix()) { - os << indent << indent << indent << "position: {\n"; + out = fmt::format_to(out, "{}{}{}position: {{\n", indent, indent, indent); auto ck = *pip.get_clustering_key_prefix(); auto type_iterator = ck.get_compound_type(p._schema)->types().begin(); auto column_iterator = p._schema.clustering_key_columns().begin(); - os << indent << indent << indent << indent << "bound_weight: " << int32_t(pip.get_bound_weight()) << ",\n"; + out = fmt::format_to(out, "{}{}{}{}bound_weight: {},\n", indent, indent, indent, indent, + int32_t(pip.get_bound_weight())); for (auto&& e : ck.components(p._schema)) { - os << indent << indent << indent << indent << "'" << column_iterator->name_as_text() - << "': " << (*type_iterator)->to_string(to_bytes(e)) << ",\n"; + out = fmt::format_to(out, "{}{}{}{}'{}': {},\n", indent, indent, indent, indent, + column_iterator->name_as_text(), + (*type_iterator)->to_string(to_bytes(e))); ++type_iterator; ++column_iterator; } - os << indent << indent << indent << "},\n"; + out = fmt::format_to(out, "{}{}{}}},\n", indent, indent, indent); } row.cells().for_each_cell([&] (column_id& c_id, const atomic_cell_or_collection& cell) { auto& column_def = p._schema.column_at(column_kind::regular_column, c_id); - os << indent << indent << indent << "'" << column_def.name_as_text() - << "': " << atomic_cell_or_collection::printer(column_def, cell) << ",\n"; + out = fmt::format_to(out, "{}{}{}'{}': {},\n", indent, indent, indent, + column_def.name_as_text(), + atomic_cell_or_collection::printer(column_def, cell)); }); - os << indent << indent << "},\n"; + out = fmt::format_to(out, "{}{}}},\n", indent, indent); } - os << indent << "]\n}"; - - return os; + return fmt::format_to(out, "{}]\n}}", indent); } constexpr gc_clock::duration row_marker::no_ttl; diff --git a/mutation/mutation_partition.hh b/mutation/mutation_partition.hh index 1f6dda199c..9c048a5d22 100644 --- a/mutation/mutation_partition.hh +++ b/mutation/mutation_partition.hh @@ -1263,9 +1263,10 @@ public: printer(const printer&) = delete; printer(printer&&) = delete; - friend std::ostream& operator<<(std::ostream& os, const printer& p); + friend ::fmt::formatter; }; - friend std::ostream& operator<<(std::ostream& os, const printer& p); + friend ::fmt::formatter; + public: // Makes sure there is a dummy entry after all clustered rows. Doesn't affect continuity. // Doesn't invalidate iterators. @@ -1503,3 +1504,7 @@ mutation_partition& mutation_partition::container_of(rows_type& rows) { bool has_any_live_data(const schema& s, column_kind kind, const row& cells, tombstone tomb = tombstone(), gc_clock::time_point now = gc_clock::time_point::min()); + +template <> struct fmt::formatter : fmt::formatter { + auto format(const mutation_partition::printer&, fmt::format_context& ctx) const -> decltype(ctx.out()); +};