osaf/libs/core/cplusplus/base/buffer.h                  |   26 +-
 osaf/libs/core/cplusplus/base/log_message.cc            |  106 -------------
 osaf/libs/core/cplusplus/base/log_message.h             |  126 +++++++++++++++-
 osaf/libs/core/cplusplus/base/tests/log_message_test.cc |   14 +-
 osaf/libs/core/mds/mds_log.cc                           |    4 +-
 5 files changed, 141 insertions(+), 135 deletions(-)


Make the use of temporary Buffer instances on the stack more efficient, by
storing the buffer data in a character array inside the class instead of
allocating it dynamically.

diff --git a/osaf/libs/core/cplusplus/base/buffer.h 
b/osaf/libs/core/cplusplus/base/buffer.h
--- a/osaf/libs/core/cplusplus/base/buffer.h
+++ b/osaf/libs/core/cplusplus/base/buffer.h
@@ -25,19 +25,14 @@
 
 namespace base {
 
-// An output buffer that can be used to build e.g. a message to be sent over a
-// network.
+// An output buffer with enough space to store @a Capacity bytes of data. It 
can
+// be used to build e.g. a message to be sent over a network.
+template <size_t Capacity>
 class Buffer {
  public:
-  // Allocate a buffer with enough space to store @a capacity bytes of data.
-  explicit Buffer(size_t capacity) :
-      buffer_{new char[capacity]},
-      capacity_{capacity},
+  Buffer() :
       size_{0} {
   }
-  ~Buffer() {
-    delete [] buffer_;
-  }
   // Reset the write position to the start of the buffer.
   void clear() { size_ = 0; }
   // Returns true if the buffer is empty.
@@ -45,16 +40,18 @@ class Buffer {
   // Returns a pointer to the start of the buffer.
   const char* data() const { return buffer_; }
   // Returns a pointer to the end of the buffer where new data can be appended.
-  char* end() const { return buffer_ + size_; }
+  char* end() { return buffer_ + size_; }
+  // Returns a read-only pointer to the end of the buffer.
+  const char* end() const { return buffer_ + size_; }
   // Returns the number of bytes that have been written to the buffer.
   size_t size() const { return size_; }
   // Set new size of the buffer (e.g. after manually adding data at the end).
   void set_size(size_t s) { size_ = s; }
   // Returns the maximum number of bytes that can be stored in this buffer.
-  size_t capacity() const { return capacity_; }
+  static size_t capacity() { return Capacity; }
   // Append a single character to the end of the buffer.
   void AppendChar(char c) {
-    if (size_ != capacity_) buffer_[size_++] = c;
+    if (size_ != Capacity) buffer_[size_++] = c;
   }
   // This function is similar to AppendNumber(), except that leading zeros will
   // be printed - i.e. this method implements a fixed field width.
@@ -77,7 +74,7 @@ class Buffer {
   }
   // Append a string of @a size characters to the end of the buffer.
   void AppendString(const char* str, size_t size) {
-    size_t bytes_to_copy = capacity_ - size_;
+    size_t bytes_to_copy = Capacity - size_;
     if (size < bytes_to_copy) bytes_to_copy = size;
     memcpy(buffer_ + size_, str, bytes_to_copy);
     size_ += bytes_to_copy;
@@ -88,9 +85,8 @@ class Buffer {
   }
 
  private:
-  char* buffer_;
-  size_t capacity_;
   size_t size_;
+  char buffer_[Capacity];
 
   DELETE_COPY_AND_MOVE_OPERATORS(Buffer);
 };
diff --git a/osaf/libs/core/cplusplus/base/log_message.cc 
b/osaf/libs/core/cplusplus/base/log_message.cc
--- a/osaf/libs/core/cplusplus/base/log_message.cc
+++ b/osaf/libs/core/cplusplus/base/log_message.cc
@@ -16,115 +16,9 @@
  */
 
 #include "osaf/libs/core/cplusplus/base/log_message.h"
-#include <time.h>
-#include <cstdint>
-#include "osaf/libs/core/common/include/osaf_time.h"
-#include "osaf/libs/core/cplusplus/base/buffer.h"
-#include "osaf/libs/core/cplusplus/base/time.h"
 
 namespace base {
 
 const struct timespec LogMessage::kNullTime{0, -1};
 
-void LogMessage::Write(Facility facility, Severity severity,
-                       const struct timespec& time_stamp,
-                       const HostName& host_name,
-                       const AppName& app_name,
-                       const ProcId& proc_id,
-                       const MsgId& msg_id,
-                       const StructuredElements& structured_elements,
-                       const std::string& message,
-                       Buffer* buffer) {
-  uint32_t priority = static_cast<uint32_t>(facility) * uint32_t{8}
-      + static_cast<uint32_t>(severity);
-  buffer->AppendChar('<');
-  buffer->AppendNumber(priority, 100);
-  buffer->AppendString(">1 ", 3);
-  WriteTime(time_stamp, buffer);
-  buffer->AppendChar(' ');
-  buffer->AppendString(host_name.data(), host_name.size());
-  buffer->AppendChar(' ');
-  buffer->AppendString(app_name.data(), app_name.size());
-  buffer->AppendChar(' ');
-  buffer->AppendString(proc_id.data(), proc_id.size());
-  buffer->AppendChar(' ');
-  buffer->AppendString(msg_id.data(), msg_id.size());
-  buffer->AppendChar(' ');
-  if (structured_elements.empty()) {
-    buffer->AppendChar('-');
-  } else {
-    for (const auto& elem : structured_elements) elem.Write(buffer);
-  }
-  if (!message.empty()) {
-    buffer->AppendChar(' ');
-    buffer->AppendString(message.data(), message.size());
-  }
-}
-
-void LogMessage::WriteTime(const struct timespec& ts, Buffer* buffer) {
-  struct tm local_time;
-  struct tm* local_ptr = localtime_r(&ts.tv_sec, &local_time);
-  if (local_ptr != nullptr && local_ptr->tm_year >= -1900
-      && local_ptr->tm_year <= (9999 - 1900)
-      && ts.tv_nsec >= 0 && ts.tv_nsec < kNanosPerSec) {
-    buffer->AppendFixedWidthNumber(local_ptr->tm_year + 1900, 1000);
-    buffer->AppendChar('-');
-    buffer->AppendFixedWidthNumber(local_ptr->tm_mon + 1, 10);
-    buffer->AppendChar('-');
-    buffer->AppendFixedWidthNumber(local_ptr->tm_mday, 10);
-    buffer->AppendChar('T');
-    buffer->AppendFixedWidthNumber(local_ptr->tm_hour, 10);
-    buffer->AppendChar(':');
-    buffer->AppendFixedWidthNumber(local_ptr->tm_min, 10);
-    buffer->AppendChar(':');
-    buffer->AppendFixedWidthNumber(local_ptr->tm_sec, 10);
-    uint32_t decimals = ts.tv_nsec / 1000;
-    if (decimals != 0) {
-      uint32_t power = 100000;
-      while (decimals % 10 == 0) {
-        decimals /= 10;
-        power /= 10;
-      }
-      buffer->AppendChar('.');
-      buffer->AppendFixedWidthNumber(decimals, power);
-    }
-    char* buf = buffer->end();
-    if ((buffer->capacity() - buffer->size()) >= 6 &&
-        strftime(buf, 6, "%z", local_ptr) == 5) {
-      if (buf[1] != '0' || buf[2] != '0' ||
-          buf[3] != '0' || buf[4] != '0') {
-        buf[5] = buf[4];
-        buf[4] = buf[3];
-        buf[3] = ':';
-        buffer->set_size(buffer->size() + 6);
-      } else {
-        buffer->AppendChar('Z');
-      }
-    }
-  } else {
-    buffer->AppendChar('-');
-  }
-}
-
-void LogMessage::Element::Write(Buffer* buffer) const {
-  buffer->AppendChar('[');
-  buffer->AppendString(id_.data(), id_.size());
-  for (const Parameter& param : parameter_list_) {
-    buffer->AppendChar(' ');
-    param.Write(buffer);
-  }
-  buffer->AppendChar(']');
-}
-
-void LogMessage::Parameter::Write(Buffer* buffer) const {
-  buffer->AppendString(name_.data(), name_.size());
-  buffer->AppendChar('=');
-  buffer->AppendChar('"');
-  for (const char& c : value_) {
-    if (c == '"' || c == '\\' || c == ']') buffer->AppendChar('\\');
-    buffer->AppendChar(c);
-  }
-  buffer->AppendChar('"');
-}
-
 }  // namespace base
diff --git a/osaf/libs/core/cplusplus/base/log_message.h 
b/osaf/libs/core/cplusplus/base/log_message.h
--- a/osaf/libs/core/cplusplus/base/log_message.h
+++ b/osaf/libs/core/cplusplus/base/log_message.h
@@ -18,13 +18,19 @@
 #ifndef OSAF_LIBS_CORE_CPLUSPLUS_BASE_LOG_MESSAGE_H_
 #define OSAF_LIBS_CORE_CPLUSPLUS_BASE_LOG_MESSAGE_H_
 
+#include <time.h>
+#include <cstddef>
+#include <cstdint>
 #include <list>
 #include <set>
 #include <string>
+#include "osaf/libs/core/common/include/osaf_time.h"
+#include "osaf/libs/core/cplusplus/base/buffer.h"
+#include "osaf/libs/core/cplusplus/base/time.h"
 
 namespace base {
 
-class Buffer;
+template <size_t Capacity> class Buffer;
 
 // The LogMessage class implements support for formatting log records according
 // to RFC 5424
@@ -135,7 +141,8 @@ class LogMessage {
     Parameter(const SdName& name, const std::string& value) :
         name_{name},
         value_{value} {}
-    void Write(Buffer* buffer) const;
+    template <size_t Capacity>
+    void Write(Buffer<Capacity>* buffer) const;
     bool operator==(const Parameter& param) const {
       return name_ == param.name_ && value_ == param.value_;
     }
@@ -153,7 +160,8 @@ class LogMessage {
             const ParameterList& parameter_list) :
         id_{id},
         parameter_list_{parameter_list} {}
-    void Write(Buffer* buffer) const;
+    template <size_t Capacity>
+    void Write(Buffer<Capacity>* buffer) const;
     bool operator<(const Element& elem) const { return id_ < elem.id_; }
     bool operator==(const Element& elem) const {
       return id_ == elem.id_ && parameter_list_ == elem.parameter_list_;
@@ -169,6 +177,7 @@ class LogMessage {
   static const struct timespec kNullTime;
   // Format a log record according to rfc5424 and write it to the provided
   // buffer.
+  template <size_t Capacity>
   static void Write(Facility facility, Severity severity,
                     const struct timespec& time_stamp,
                     const HostName& host_name,
@@ -177,10 +186,117 @@ class LogMessage {
                     const MsgId& msg_id,
                     const StructuredElements& structured_elements,
                     const std::string& message,
-                    Buffer* buffer);
-  static void WriteTime(const struct timespec& ts, Buffer* buffer);
+                    Buffer<Capacity>* buffer);
+  template <size_t Capacity>
+  static void WriteTime(const struct timespec& ts, Buffer<Capacity>* buffer);
 };
 
+template <size_t Capacity>
+void LogMessage::Write(Facility facility, Severity severity,
+                       const struct timespec& time_stamp,
+                       const HostName& host_name,
+                       const AppName& app_name,
+                       const ProcId& proc_id,
+                       const MsgId& msg_id,
+                       const StructuredElements& structured_elements,
+                       const std::string& message,
+                       Buffer<Capacity>* buffer) {
+  uint32_t priority = static_cast<uint32_t>(facility) * uint32_t{8}
+      + static_cast<uint32_t>(severity);
+  buffer->AppendChar('<');
+  buffer->AppendNumber(priority, 100);
+  buffer->AppendString(">1 ", 3);
+  WriteTime(time_stamp, buffer);
+  buffer->AppendChar(' ');
+  buffer->AppendString(host_name.data(), host_name.size());
+  buffer->AppendChar(' ');
+  buffer->AppendString(app_name.data(), app_name.size());
+  buffer->AppendChar(' ');
+  buffer->AppendString(proc_id.data(), proc_id.size());
+  buffer->AppendChar(' ');
+  buffer->AppendString(msg_id.data(), msg_id.size());
+  buffer->AppendChar(' ');
+  if (structured_elements.empty()) {
+    buffer->AppendChar('-');
+  } else {
+    for (const auto& elem : structured_elements) elem.Write(buffer);
+  }
+  if (!message.empty()) {
+    buffer->AppendChar(' ');
+    buffer->AppendString(message.data(), message.size());
+  }
+}
+
+template <size_t Capacity>
+void LogMessage::WriteTime(const struct timespec& ts,
+                           Buffer<Capacity>* buffer) {
+  struct tm local_time;
+  struct tm* local_ptr = localtime_r(&ts.tv_sec, &local_time);
+  if (local_ptr != nullptr && local_ptr->tm_year >= -1900
+      && local_ptr->tm_year <= (9999 - 1900)
+      && ts.tv_nsec >= 0 && ts.tv_nsec < kNanosPerSec) {
+    buffer->AppendFixedWidthNumber(local_ptr->tm_year + 1900, 1000);
+    buffer->AppendChar('-');
+    buffer->AppendFixedWidthNumber(local_ptr->tm_mon + 1, 10);
+    buffer->AppendChar('-');
+    buffer->AppendFixedWidthNumber(local_ptr->tm_mday, 10);
+    buffer->AppendChar('T');
+    buffer->AppendFixedWidthNumber(local_ptr->tm_hour, 10);
+    buffer->AppendChar(':');
+    buffer->AppendFixedWidthNumber(local_ptr->tm_min, 10);
+    buffer->AppendChar(':');
+    buffer->AppendFixedWidthNumber(local_ptr->tm_sec, 10);
+    uint32_t decimals = ts.tv_nsec / 1000;
+    if (decimals != 0) {
+      uint32_t power = 100000;
+      while (decimals % 10 == 0) {
+        decimals /= 10;
+        power /= 10;
+      }
+      buffer->AppendChar('.');
+      buffer->AppendFixedWidthNumber(decimals, power);
+    }
+    char* buf = buffer->end();
+    if ((buffer->capacity() - buffer->size()) >= 6 &&
+        strftime(buf, 6, "%z", local_ptr) == 5) {
+      if (buf[1] != '0' || buf[2] != '0' ||
+          buf[3] != '0' || buf[4] != '0') {
+        buf[5] = buf[4];
+        buf[4] = buf[3];
+        buf[3] = ':';
+        buffer->set_size(buffer->size() + 6);
+      } else {
+        buffer->AppendChar('Z');
+      }
+    }
+  } else {
+    buffer->AppendChar('-');
+  }
+}
+
+template <size_t Capacity>
+void LogMessage::Element::Write(Buffer<Capacity>* buffer) const {
+  buffer->AppendChar('[');
+  buffer->AppendString(id_.data(), id_.size());
+  for (const Parameter& param : parameter_list_) {
+    buffer->AppendChar(' ');
+    param.Write(buffer);
+  }
+  buffer->AppendChar(']');
+}
+
+template <size_t Capacity>
+void LogMessage::Parameter::Write(Buffer<Capacity>* buffer) const {
+  buffer->AppendString(name_.data(), name_.size());
+  buffer->AppendChar('=');
+  buffer->AppendChar('"');
+  for (const char& c : value_) {
+    if (c == '"' || c == '\\' || c == ']') buffer->AppendChar('\\');
+    buffer->AppendChar(c);
+  }
+  buffer->AppendChar('"');
+}
+
 }  // namespace base
 
 #endif  // OSAF_LIBS_CORE_CPLUSPLUS_BASE_LOG_MESSAGE_H_
diff --git a/osaf/libs/core/cplusplus/base/tests/log_message_test.cc 
b/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
--- a/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
+++ b/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
@@ -39,7 +39,7 @@ static const char null_text[] = "<0>1 - 
 TEST(LogMessageTest, WriteHelloWorld1) {
   setenv("TZ", "Europe/Stockholm", 1);
   tzset();
-  base::Buffer buf{256};
+  base::Buffer<256> buf{};
   base::LogMessage::Write(
       base::LogMessage::Facility::kLocal0,
       base::LogMessage::Severity::kNotice,
@@ -66,7 +66,7 @@ TEST(LogMessageTest, WriteHelloWorld1) {
 TEST(LogMessageTest, WriteHelloWorld2) {
   setenv("TZ", "Europe/Stockholm", 1);
   tzset();
-  base::Buffer buf{256};
+  base::Buffer<256> buf{};
   base::LogMessage::Write(
       base::LogMessage::Facility::kLocal7,
       base::LogMessage::Severity::kDebug,
@@ -93,7 +93,7 @@ TEST(LogMessageTest, WriteHelloWorld2) {
 TEST(LogMessageTest, WriteNullMessage) {
   setenv("TZ", "Europe/Stockholm", 1);
   tzset();
-  base::Buffer buf(256);
+  base::Buffer<256> buf{};
   base::LogMessage::Write(
       base::LogMessage::Facility::kKern,
       base::LogMessage::Severity::kEmerg,
@@ -116,7 +116,7 @@ TEST(LogMessageTest, WriteNullMessage) {
 TEST(LogMessageTimeTest, WriteBCTime) {
   setenv("TZ", "Europe/Stockholm", 1);
   tzset();
-  base::Buffer buf(256);
+  base::Buffer<256> buf{};
   base::LogMessage::WriteTime({-62188992000, 0}, &buf);
   EXPECT_EQ(buf.size(), 1);
   EXPECT_EQ(memcmp(buf.data(), "-", 1), 0);
@@ -125,7 +125,7 @@ TEST(LogMessageTimeTest, WriteBCTime) {
 TEST(LogMessageTimeTest, WriteFarFutureTime) {
   setenv("TZ", "Europe/Stockholm", 1);
   tzset();
-  base::Buffer buf(256);
+  base::Buffer<256> buf{};
   base::LogMessage::WriteTime({253423296000, 0}, &buf);
   EXPECT_EQ(buf.size(), 1);
   EXPECT_EQ(memcmp(buf.data(), "-", 1), 0);
@@ -136,7 +136,7 @@ TEST(LogMessageTimeTest, WriteTimeInSmal
   static const char expected_result[] = "2016-10-10T16:24:02.505489";
   setenv("TZ", "Europe/Stockholm", 1);
   tzset();
-  base::Buffer buf(30);
+  base::Buffer<30> buf{};
   base::LogMessage::WriteTime({1476109442, 505489184}, &buf);
   EXPECT_EQ(buf.size(), sizeof(expected_result) - 1);
   EXPECT_EQ(memcmp(buf.data(), expected_result, buf.size()), 0);
@@ -146,7 +146,7 @@ TEST(LogMessageTimeTest, WriteTimeWithUt
   static const char expected_result[] = "2016-10-10T14:33:32.82328Z";
   setenv("TZ", "UTC", 1);
   tzset();
-  base::Buffer buf(256);
+  base::Buffer<256> buf{};
   base::LogMessage::WriteTime({1476110012, 823280288}, &buf);
   EXPECT_EQ(buf.size(), sizeof(expected_result) - 1);
   EXPECT_EQ(memcmp(buf.data(), expected_result, buf.size()), 0);
diff --git a/osaf/libs/core/mds/mds_log.cc b/osaf/libs/core/mds/mds_log.cc
--- a/osaf/libs/core/mds/mds_log.cc
+++ b/osaf/libs/core/mds/mds_log.cc
@@ -59,7 +59,7 @@ class MdsLog {
   base::LogMessage::AppName app_name_;
   base::LogMessage::ProcId proc_id_;
   uint64_t msg_id_;
-  base::Buffer buffer_;
+  base::Buffer<512> buffer_;
   base::UnixClientSocket log_socket_;
 
   DELETE_COPY_AND_MOVE_OPERATORS(MdsLog);
@@ -75,7 +75,7 @@ MdsLog::MdsLog(const char* host_name, co
     app_name_{base::LogMessage::AppName{app_name}},
     proc_id_{base::LogMessage::ProcId{std::to_string(proc_id)}},
     msg_id_{0},
-    buffer_{512},
+    buffer_{},
     log_socket_{socket_name} {
   pthread_mutexattr_t attr;
   int result = pthread_mutexattr_init(&attr);

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to