]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/log/Entry.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / log / Entry.h
index bbcd17988b2ed410a75f93850d687bfe74f38620..a8479b53beecb72ed4fd416b944304837d5359bb 100644 (file)
 #ifndef __CEPH_LOG_ENTRY_H
 #define __CEPH_LOG_ENTRY_H
 
-#include "include/utime.h"
-#include "common/PrebufferedStreambuf.h"
+#include "log/LogClock.h"
+
+#include "common/StackStringStream.h"
+
+#include "boost/container/small_vector.hpp"
+
 #include <pthread.h>
-#include <string>
 
+#include <string_view>
 
 namespace ceph {
 namespace logging {
 
-struct Entry {
-  utime_t m_stamp;
+class Entry {
+public:
+  using time = log_time;
+
+  Entry() = delete;
+  Entry(short pr, short sub) :
+    m_stamp(clock().now()),
+    m_thread(pthread_self()),
+    m_prio(pr),
+    m_subsys(sub)
+  {}
+  Entry(const Entry &) = default;
+  Entry& operator=(const Entry &) = default;
+  Entry(Entry &&e) = default;
+  Entry& operator=(Entry &&e) = default;
+  virtual ~Entry() = default;
+
+  virtual std::string_view strv() const = 0;
+  virtual std::size_t size() const = 0;
+
+  time m_stamp;
   pthread_t m_thread;
   short m_prio, m_subsys;
-  Entry *m_next;
-
-  PrebufferedStreambuf m_streambuf;
-  size_t m_buf_len;
-  size_t* m_exp_len;
-  char m_static_buf[1];
-
-  Entry()
-    : m_thread(0), m_prio(0), m_subsys(0),
-      m_next(NULL),
-      m_streambuf(m_static_buf, sizeof(m_static_buf)),
-      m_buf_len(sizeof(m_static_buf)),
-      m_exp_len(NULL)
-  {}
-  Entry(utime_t s, pthread_t t, short pr, short sub,
-  const char *msg = NULL)
-      : m_stamp(s), m_thread(t), m_prio(pr), m_subsys(sub),
-        m_next(NULL),
-        m_streambuf(m_static_buf, sizeof(m_static_buf)),
-        m_buf_len(sizeof(m_static_buf)),
-        m_exp_len(NULL)
-    {
-      if (msg) {
-        ostream os(&m_streambuf);
-        os << msg;
-      }
-    }
-  Entry(utime_t s, pthread_t t, short pr, short sub, char* buf, size_t buf_len, size_t* exp_len,
-       const char *msg = NULL)
-    : m_stamp(s), m_thread(t), m_prio(pr), m_subsys(sub),
-      m_next(NULL),
-      m_streambuf(buf, buf_len),
-      m_buf_len(buf_len),
-      m_exp_len(exp_len)
-  {
-    if (msg) {
-      ostream os(&m_streambuf);
-      os << msg;
-    }
-  }
 
 private:
-  ~Entry() = default;
+  static log_clock& clock() {
+    static log_clock clock;
+    return clock;
+  }
+};
 
+/* This should never be moved to the heap! Only allocate this on the stack. See
+ * CachedStackStringStream for rationale.
+ */
+class MutableEntry : public Entry {
 public:
-  // function improves estimate for expected size of message
-  void hint_size() {
-    if (m_exp_len != NULL) {
-      size_t size = m_streambuf.size();
-      if (size > __atomic_load_n(m_exp_len, __ATOMIC_RELAXED)) {
-        //log larger then expected, just expand
-        __atomic_store_n(m_exp_len, size + 10, __ATOMIC_RELAXED);
-      }
-      else {
-        //asymptotically adapt expected size to message size
-        __atomic_store_n(m_exp_len, (size + 10 + m_buf_len*31) / 32, __ATOMIC_RELAXED);
-      }
-    }
+  MutableEntry() = delete;
+  MutableEntry(short pr, short sub) : Entry(pr, sub) {}
+  MutableEntry(const MutableEntry&) = delete;
+  MutableEntry& operator=(const MutableEntry&) = delete;
+  MutableEntry(MutableEntry&&) = delete;
+  MutableEntry& operator=(MutableEntry&&) = delete;
+  ~MutableEntry() override = default;
+
+  std::ostream& get_ostream() {
+    return *cos;
   }
 
-  void set_str(const std::string &s) {
-    ostream os(&m_streambuf);
-    os << s;
+  std::string_view strv() const override {
+    return cos->strv();
   }
-
-  std::string get_str() const {
-    return m_streambuf.get_str();
+  std::size_t size() const override {
+    return cos->strv().size();
   }
 
-  // returns current size of content
-  size_t size() const {
-    return m_streambuf.size();
-  }
+private:
+  CachedStackStringStream cos;
+};
 
-  // extracts up to avail chars of content
-  int snprintf(char* dst, size_t avail) const {
-    return m_streambuf.snprintf(dst, avail);
+class ConcreteEntry : public Entry {
+public:
+  ConcreteEntry() = delete;
+  ConcreteEntry(const Entry& e) : Entry(e) {
+    auto strv = e.strv();
+    str.reserve(strv.size());
+    str.insert(str.end(), strv.begin(), strv.end());
   }
+  ConcreteEntry& operator=(const Entry& e) {
+    Entry::operator=(e);
+    auto strv = e.strv();
+    str.reserve(strv.size());
+    str.assign(strv.begin(), strv.end());
+    return *this;
+  }
+  ConcreteEntry(ConcreteEntry&& e) : Entry(e), str(std::move(e.str)) {}
+  ConcreteEntry& operator=(ConcreteEntry&& e) {
+    Entry::operator=(e);
+    str = std::move(e.str);
+    return *this;
+  }
+  ~ConcreteEntry() override = default;
 
-  void destroy() {
-    if (m_exp_len != NULL) {
-      this->~Entry();
-      ::operator delete(this);
-    } else {
-      delete(this);
-    }
+  std::string_view strv() const override {
+    return std::string_view(str.data(), str.size());
+  }
+  std::size_t size() const override {
+    return str.size();
   }
+
+private:
+  boost::container::small_vector<char, 1024> str;
 };
 
 }