From 91497e46331b4755b9ff23b7ba11e631d64413ac Mon Sep 17 00:00:00 2001 From: Adam Kupczyk Date: Mon, 19 Oct 2015 12:20:37 +0200 Subject: [PATCH] Speed optimizations. Merged 3 writes into 1. Got rid of std::string construction. More unification on syslog,stderr,fd. Signed-off-by: Adam Kupczyk --- src/common/PrebufferedStreambuf.cc | 41 +++++++++++++++++++++++++++++- src/common/PrebufferedStreambuf.h | 8 +++++- src/include/utime.h | 12 ++++++++- src/log/Entry.h | 10 ++++++++ src/log/Log.cc | 30 ++++++++++------------ 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/src/common/PrebufferedStreambuf.cc b/src/common/PrebufferedStreambuf.cc index d6db8bbe0af21..d160176813309 100644 --- a/src/common/PrebufferedStreambuf.cc +++ b/src/common/PrebufferedStreambuf.cc @@ -1,6 +1,6 @@ #include "common/PrebufferedStreambuf.h" - +#include PrebufferedStreambuf::PrebufferedStreambuf(char *buf, size_t len) : m_buf(buf), m_buf_len(len) { @@ -61,3 +61,42 @@ std::string PrebufferedStreambuf::get_str() const return std::string(m_buf, this->pptr() - m_buf); } } +// returns current size of content +size_t PrebufferedStreambuf::size() const +{ + if(m_overflow.size() == 0) { + return this->pptr() - m_buf; + } else { + return m_buf_len + m_overflow.size(); + } +} + +// extracts up to avail chars of content +int PrebufferedStreambuf::snprintf(char* dst, size_t avail) const +{ + size_t o_size=m_overflow.size(); + size_t len_a; + size_t len_b; + if(o_size>0){ + len_a = m_buf_len; + len_b = o_size; + } else { + len_a = this->pptr() - m_buf; + len_b = 0; + } + if(avail > len_a + len_b ) { + memcpy(dst, m_buf, len_a); + memcpy(dst + m_buf_len, m_overflow.c_str(), len_b); + dst[len_a + len_b] = 0; + } else { + if(avail > len_a ) { + memcpy(dst, m_buf, len_a); + memcpy(dst + m_buf_len, m_overflow.c_str(), avail - len_a - 1); + dst[avail - 1] = 0; + } else { + memcpy(dst, m_buf, avail - 1); + dst[avail - 1] = 0; + } + } + return len_a + len_b; +} diff --git a/src/common/PrebufferedStreambuf.h b/src/common/PrebufferedStreambuf.h index 80a89aa43f3ea..ac123810b6bc0 100644 --- a/src/common/PrebufferedStreambuf.h +++ b/src/common/PrebufferedStreambuf.h @@ -37,6 +37,12 @@ class PrebufferedStreambuf /// return a string copy (inefficiently) std::string get_str() const; -}; + + // returns current size of content + size_t size() const; + + // extracts up to avail chars of content + int snprintf(char* dst, size_t avail) const; +}; #endif diff --git a/src/include/utime.h b/src/include/utime.h index 30780d1af3937..27241e0b32425 100644 --- a/src/include/utime.h +++ b/src/include/utime.h @@ -239,12 +239,22 @@ class utime_t { time_t tt = sec(); localtime_r(&tt, &bdt); - return snprintf(out, outlen, + return ::snprintf(out, outlen, "%04d-%02d-%02d %02d:%02d:%02d.%06ld", bdt.tm_year + 1900, bdt.tm_mon + 1, bdt.tm_mday, bdt.tm_hour, bdt.tm_min, bdt.tm_sec, usec()); } + static int snprintf(char *out, int outlen, time_t tt) { + struct tm bdt; + localtime_r(&tt, &bdt); + + return ::snprintf(out, outlen, + "%04d-%02d-%02d %02d:%02d:%02d", + bdt.tm_year + 1900, bdt.tm_mon + 1, bdt.tm_mday, + bdt.tm_hour, bdt.tm_min, bdt.tm_sec); + } + static int parse_date(const string& date, uint64_t *epoch, uint64_t *nsec, string *out_date=NULL, string *out_time=NULL) { struct tm tm; diff --git a/src/log/Entry.h b/src/log/Entry.h index 7cdf11612acbf..02217609d28f3 100644 --- a/src/log/Entry.h +++ b/src/log/Entry.h @@ -48,6 +48,16 @@ struct Entry { std::string get_str() const { return m_streambuf.get_str(); } + + // returns current size of content + size_t size() const { + return m_streambuf.size(); + } + + // extracts up to avail chars of content + int snprintf(char* dst, size_t avail) const { + return m_streambuf.snprintf(dst, avail); + } }; } diff --git a/src/log/Log.cc b/src/log/Log.cc index 3dc6c631061a5..e4ce80a09b7d2 100644 --- a/src/log/Log.cc +++ b/src/log/Log.cc @@ -209,7 +209,6 @@ void Log::flush() void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash) { Entry *e; - char buf[80]; while ((e = t->dequeue()) != NULL) { unsigned sub = e->m_subsys; @@ -219,7 +218,8 @@ void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash) bool do_stderr = m_stderr_crash >= e->m_prio && should_log; if (do_fd || do_syslog || do_stderr) { - int buflen = 0; + size_t buflen = 0; + char buf[80 + e->size()]; if (crash) buflen += snprintf(buf, sizeof(buf), "%6d> ", -t->m_len); @@ -227,25 +227,23 @@ void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash) buflen += snprintf(buf + buflen, sizeof(buf)-buflen, " %lx %2d ", (unsigned long)e->m_thread, e->m_prio); - // FIXME: this is slow - string s = e->get_str(); - - if (do_fd) { - int r = safe_write(m_fd, buf, buflen); - if (r >= 0) - r = safe_write(m_fd, s.data(), s.size()); - if (r >= 0) - r = write(m_fd, "\n", 1); - if (r < 0) - cerr << "problem writing to " << m_log_file << ": " << cpp_strerror(r) << std::endl; - } + buflen += e->snprintf(buf + buflen, sizeof(buf) - buflen - 1 ); + if(buflen > sizeof(buf) - 1 ) //paranoid check, buf was declared to hold everything + buflen = sizeof(buf) - 1; if (do_syslog) { - syslog(LOG_USER, "%s%s", buf, s.c_str()); + syslog(LOG_USER, "%s", buf); } if (do_stderr) { - cerr << buf << s << std::endl; + cerr << buf << std::endl; + } + if (do_fd) { + buf[buflen-1]='\n'; + buf[buflen]='\0'; + int r=safe_write(m_fd, buf, buflen+1); + if (r < 0) + cerr << "problem writing to " << m_log_file << ": " << cpp_strerror(r) << std::endl; } }