]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
common: improve hobject_t fmtlib formatter performance
authorRonen Friedman <rfriedma@redhat.com>
Sun, 18 Feb 2024 06:32:10 +0000 (00:32 -0600)
committerRonen Friedman <rfriedma@redhat.com>
Wed, 21 Feb 2024 14:07:06 +0000 (08:07 -0600)
The new version of the code only takes about 38% of the time of the old
one.  See https://github.com/ronen-fr/hobjtostr/tree/rf-2 for the code
used to benchmark the new version.

hobject_fmt.h is folded into hobject.h, as fmtlib is now an accepted
dependency in all of Ceph.

Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
src/common/hobject.h
src/common/hobject_fmt.h [deleted file]
src/crimson/osd/backfill_state.cc
src/crimson/osd/pg.cc
src/crimson/osd/scrub/scrub_machine.h
src/msg/msg_types.h
src/osd/osd_types_fmt.h

index fe7f9a705c9814317cf42834d2df7482d3c3dd98..d8754550a0daed34e0433e0a1a94716df9608916 100644 (file)
@@ -15,6 +15,9 @@
 #ifndef __CEPH_OS_HOBJECT_H
 #define __CEPH_OS_HOBJECT_H
 
+#include <fmt/compile.h>
+#include <fmt/format.h>
+
 #if FMT_VERSION >= 90000
 #include <fmt/ostream.h>
 #endif
@@ -351,6 +354,54 @@ template<> struct hash<hobject_t> {
 };
 } // namespace std
 
+namespace fmt {
+template <>
+struct formatter<hobject_t> {
+
+  template <typename FormatContext>
+  static inline auto
+  append_sanitized(FormatContext& ctx, const std::string& in, int sep = 0)
+  {
+    for (const auto i : in) {
+      if (i == '%' || i == ':' || i == '/' || i < 32 || i >= 127) {
+       fmt::format_to(
+           ctx.out(), FMT_COMPILE("%{:02x}"), static_cast<unsigned char>(i));
+      } else {
+       fmt::format_to(ctx.out(), FMT_COMPILE("{:c}"), i);
+      }
+    }
+    if (sep) {
+      fmt::format_to(
+         ctx.out(), FMT_COMPILE("{:c}"), sep);
+    }
+    return ctx.out();
+  }
+
+  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+  template <typename FormatContext>
+  auto format(const hobject_t& ho, FormatContext& ctx)
+  {
+    if (ho == hobject_t{}) {
+      return fmt::format_to(ctx.out(), "MIN");
+    }
+
+    if (ho.is_max()) {
+      return fmt::format_to(ctx.out(), "MAX");
+    }
+
+    fmt::format_to(
+       ctx.out(), FMT_COMPILE("{}:{:08x}:"), static_cast<uint64_t>(ho.pool),
+       ho.get_bitwise_key_u32());
+    append_sanitized(ctx, ho.nspace, ':');
+    append_sanitized(ctx, ho.get_key(), ':');
+    append_sanitized(ctx, ho.oid.name);
+    return fmt::format_to(ctx.out(), FMT_COMPILE(":{}"), ho.snap);
+  }
+};
+}  // namespace fmt
+
+
 std::ostream& operator<<(std::ostream& out, const hobject_t& o);
 
 template <typename T>
diff --git a/src/common/hobject_fmt.h b/src/common/hobject_fmt.h
deleted file mode 100644 (file)
index a2a730e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-#pragma once
-
-/**
- * \file fmtlib formatters for some hobject.h classes
- */
-#include <fmt/format.h>
-#include <fmt/ranges.h>
-
-#include "common/hobject.h"
-#include "msg/msg_fmt.h"
-
-// \todo reimplement
-static inline void append_out_escaped(const std::string& in, std::string* out)
-{
-  for (auto i = in.cbegin(); i != in.cend(); ++i) {
-    if (*i == '%' || *i == ':' || *i == '/' || *i < 32 || *i >= 127) {
-      char buf[4];
-      snprintf(buf, sizeof(buf), "%%%02x", (int)(unsigned char)*i);
-      out->append(buf);
-    } else {
-      out->push_back(*i);
-    }
-  }
-}
-
-template <> struct fmt::formatter<hobject_t> {
-
-  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
-
-  template <typename FormatContext> auto format(const hobject_t& ho, FormatContext& ctx)
-  {
-    if (ho == hobject_t{}) {
-      return fmt::format_to(ctx.out(), "MIN");
-    }
-
-    if (ho.is_max()) {
-      return fmt::format_to(ctx.out(), "MAX");
-    }
-
-    std::string v;
-    append_out_escaped(ho.nspace, &v);
-    v.push_back(':');
-    append_out_escaped(ho.get_key(), &v);
-    v.push_back(':');
-    append_out_escaped(ho.oid.name, &v);
-
-    return fmt::format_to(ctx.out(), "{}:{:08x}:{}:{}", static_cast<uint64_t>(ho.pool),
-                         ho.get_bitwise_key_u32(), v, ho.snap);
-  }
-};
index 46a270ffe54db9b821c9bf4020f2f56a3be3981a..92b3ea8714cdd6b1980d9b7cc2432d6af480afa1 100644 (file)
@@ -4,7 +4,7 @@
 #include <algorithm>
 #include <boost/type_index.hpp>
 #include <fmt/ranges.h>
-#include "common/hobject_fmt.h"
+#include "common/hobject.h"
 #include "crimson/osd/backfill_state.h"
 #include "osd/osd_types_fmt.h"
 
index 54c8101cd115be2db8972104045d06a291662b13..697f4e2225ca4f63c1f7a839c4a75c49efb91d8b 100644 (file)
@@ -14,7 +14,7 @@
 #include <fmt/format.h>
 #include <fmt/ostream.h>
 
-#include "common/hobject_fmt.h"
+#include "common/hobject.h"
 
 #include "messages/MOSDOp.h"
 #include "messages/MOSDOpReply.h"
index d2d127adc0d912bcff7202c46c2c9314dbf5f4d7..f6cec5cba71ab079129d77ac124f84571b70e5bd 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "common/fmt_common.h"
 #include "common/hobject.h"
-#include "common/hobject_fmt.h"
 #include "crimson/common/log.h"
 #include "osd/osd_types_fmt.h"
 #include "scrub_validator.h"
index b39120cc08d4d51891c8ebee629cc3caa553262e..e1e3ecca749f53ee73ec6b84efdda47f35d18a93 100644 (file)
@@ -98,6 +98,15 @@ public:
   }
   void dump(ceph::Formatter *f) const;
 
+  template <typename FormatContext>
+  auto fmt_print_ctx(FormatContext& ctx) const {
+    if (is_new() || _num < 0) {
+      return fmt::format_to(ctx.out(), "{}.?", type_str());
+    } else {
+      return fmt::format_to(ctx.out(), "{}.{}",type_str(), _num);
+    }
+  }
+
   static void generate_test_instances(std::list<entity_name_t*>& o);
 };
 WRITE_CLASS_DENC(entity_name_t)
index e467d5d23044f97beb5bd690388335087d722cf4..a88bf08c5ec0ba886dbed572db4f755063cfbc69 100644 (file)
@@ -5,9 +5,10 @@
  * \file fmtlib formatters for some types.h classes
  */
 
-#include "common/hobject_fmt.h"
+#include "common/hobject.h"
 #include "osd/osd_types.h"
 #include <fmt/chrono.h>
+#include <fmt/ranges.h>
 #if FMT_VERSION >= 90000
 #include <fmt/ostream.h>
 #endif