This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


The following commit(s) were added to refs/heads/master by this push:
     new b36f3b79 Reduce logging overhead when the output is unchanged by 
encoding (#249)
b36f3b79 is described below

commit b36f3b790800cb8b81499aea750f525c2b45d14f
Author: Stephen Webb <[email protected]>
AuthorDate: Thu Aug 10 14:45:25 2023 +1000

    Reduce logging overhead when the output is unchanged by encoding (#249)
    
    * Enable LOG4CXX_MULTI_PROCESS when 
LOG4CXX_MULTIPROCESS_ROLLING_FILE_APPENDER is enabled
---
 src/main/cpp/CMakeLists.txt                       |  1 +
 src/main/cpp/charsetencoder.cpp                   | 16 ++++++++++++
 src/main/cpp/outputstreamwriter.cpp               | 30 ++++++++++++++---------
 src/main/include/log4cxx/helpers/charsetencoder.h |  6 +++++
 4 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index 9a6b6e84..e4aa0ce1 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -48,6 +48,7 @@ if(LOG4CXX_NETWORKING_SUPPORT)
 endif()
 
 if(LOG4CXX_MULTIPROCESS_ROLLING_FILE_APPENDER)
+    target_compile_definitions(log4cxx PRIVATE LOG4CXX_MULTI_PROCESS)
     list(APPEND extra_classes
        multiprocessrollingfileappender.cpp
        )
diff --git a/src/main/cpp/charsetencoder.cpp b/src/main/cpp/charsetencoder.cpp
index df61e487..ee5f5ff7 100644
--- a/src/main/cpp/charsetencoder.cpp
+++ b/src/main/cpp/charsetencoder.cpp
@@ -21,6 +21,7 @@
 #include <apr_xlate.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/transcoder.h>
+#include <algorithm>
 
 #if !defined(LOG4CXX)
        #define LOG4CXX 1
@@ -644,3 +645,18 @@ void CharsetEncoder::encode(CharsetEncoderPtr& enc,
                dst.put(Transcoder::LOSSCHAR);
        }
 }
+
+bool CharsetEncoder::isTriviallyCopyable(const LogString& src, const 
CharsetEncoderPtr& enc)
+{
+       bool result;
+#if !LOG4CXX_CHARSET_EBCDIC
+       if (dynamic_cast<LocaleCharsetEncoder*>(enc.get()))
+       {
+               result = src.end() == std::find_if(src.begin(), src.end()
+                       , [](const logchar& ch) -> bool { return 0x80 <= 
(unsigned int)ch; });
+       }
+       else
+#endif
+               result = !!dynamic_cast<TrivialCharsetEncoder*>(enc.get());
+       return result;
+}
diff --git a/src/main/cpp/outputstreamwriter.cpp 
b/src/main/cpp/outputstreamwriter.cpp
index 4ddf93c9..7c8547f0 100644
--- a/src/main/cpp/outputstreamwriter.cpp
+++ b/src/main/cpp/outputstreamwriter.cpp
@@ -78,18 +78,29 @@ void OutputStreamWriter::flush(Pool& p)
 
 void OutputStreamWriter::write(const LogString& str, Pool& p)
 {
-       if (str.length() > 0)
+       if (str.empty())
+               return;
+       if (CharsetEncoder::isTriviallyCopyable(str, m_priv->enc))
        {
+               ByteBuffer buf((char*)str.data(), str.size() * sizeof 
(logchar));
+               m_priv->out->write(buf, p);
+       }
+       else
+       {
+               enum { BUFSIZE = 1024 };
+               char stackData[BUFSIZE];
+               char* rawbuf = stackData;
+               size_t bufSize = BUFSIZE;
 #ifdef LOG4CXX_MULTI_PROCESS
+               std::vector<char> heapData;
                // Ensure the logging event is a single write system call to 
keep events from each process separate
-               size_t bufSize = str.length() * 2;
-               char* rawbuf = new char[bufSize];
-               ByteBuffer buf(rawbuf, (size_t) bufSize);
-#else
-               enum { BUFSIZE = 1024 };
-               char rawbuf[BUFSIZE];
-               ByteBuffer buf(rawbuf, (size_t) BUFSIZE);
+               if (bufSize < str.length() * 2)
+               {
+                       heapData.resize(bufSize = str.length() * 2);
+                       rawbuf = heapData.data();
+               }
 #endif
+               ByteBuffer buf(rawbuf, bufSize);
                m_priv->enc->reset();
                LogString::const_iterator iter = str.begin();
 
@@ -105,9 +116,6 @@ void OutputStreamWriter::write(const LogString& str, Pool& 
p)
                m_priv->enc->flush(buf);
                buf.flip();
                m_priv->out->write(buf, p);
-#ifdef LOG4CXX_MULTI_PROCESS
-               delete []rawbuf;
-#endif
        }
 }
 
diff --git a/src/main/include/log4cxx/helpers/charsetencoder.h 
b/src/main/include/log4cxx/helpers/charsetencoder.h
index c54e35dd..1fec9df1 100644
--- a/src/main/include/log4cxx/helpers/charsetencoder.h
+++ b/src/main/include/log4cxx/helpers/charsetencoder.h
@@ -116,6 +116,12 @@ class LOG4CXX_EXPORT CharsetEncoder : public Object
                        return (stat != 0);
                }
 
+               /**
+               * Is the data of \c src unchanged by \c enc.
+               *
+               */
+               static bool isTriviallyCopyable(const LogString& src, const 
CharsetEncoderPtr& enc);
+
 
        private:
                /**

Reply via email to