Boost logo

Boost-Commit :

From: john.groups_at_[hidden]
Date: 2007-12-29 13:15:09


Author: jtorjo
Date: 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
New Revision: 42340
URL: http://svn.boost.org/trac/boost/changeset/42340

Log:
[logging]
v0.12.13, 29 dec 2007
- added tss_ostringstream - allow faster creation of stringstreams (one stringstream per thread)
Added:
   sandbox/logging/boost/logging/detail/tss/tss_ostringstream.hpp (contents, props changed)
   sandbox/logging/lib/logging/samples/scenarios/use_tss_ostringstream.cpp (contents, props changed)
Text files modified:
   sandbox/logging/boost/logging/detail/find_gather.hpp | 22 +++++++++++-----------
   sandbox/logging/boost/logging/detail/format_msg_type.hpp | 38 +++++++++++++++++++++++++++++++++++---
   sandbox/logging/boost/logging/detail/macros.hpp | 9 ++++++---
   sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp | 3 ++-
   sandbox/logging/boost/logging/detail/raw_doc/todo.hpp | 1 +
   sandbox/logging/boost/logging/detail/ts/ts_resource.hpp | 4 ++--
   sandbox/logging/boost/logging/detail/tss/tss.hpp | 35 +++++++++++++++++++++++++++++------
   sandbox/logging/boost/logging/detail/use_format_write.hpp | 6 +++++-
   sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj | 9 +++++++++
   sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp | 4 ++--
   10 files changed, 102 insertions(+), 29 deletions(-)

Modified: sandbox/logging/boost/logging/detail/find_gather.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/find_gather.hpp (original)
+++ sandbox/logging/boost/logging/detail/find_gather.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -54,23 +54,23 @@
     }
 
     namespace detail {
- template<class param> struct find_gather {};
- template<> struct find_gather< std::basic_string<char_type> > { typedef gather::ostream_like::return_str< std::basic_string<char_type>, std::basic_ostringstream<char_type> > type ; };
+ template<class stream, class param> struct find_gather {};
+ template<class stream> struct find_gather< stream, std::basic_string<char_type> > { typedef gather::ostream_like::return_str< std::basic_string<char_type>, stream > type ; };
 
- template< class string_type>
- struct find_gather< boost::logging::optimize::cache_string_one_str<string_type> > {
- typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_one_str<string_type>, std::basic_ostringstream<char_type> > type;
+ template< class stream, class string_type>
+ struct find_gather< stream, boost::logging::optimize::cache_string_one_str<string_type> > {
+ typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_one_str<string_type>, stream > type;
         };
 
- template< class string_type>
- struct find_gather< boost::logging::optimize::cache_string_several_str<string_type,void*> > {
- typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_several_str<string_type,void*>, std::basic_ostringstream<char_type> > type;
+ template< class stream, class string_type>
+ struct find_gather< stream, boost::logging::optimize::cache_string_several_str<string_type,void*> > {
+ typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_several_str<string_type,void*>, stream > type;
         };
 
 
- template<class string, class p1, class p2, class p3, class p4, class p5, class p6, class p7, class p8, class p9, class p10>
- struct find_gather< tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> > {
- typedef gather::ostream_like::return_tag_holder< tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> , std::basic_ostringstream<char_type> > type;
+ template<class stream, class string, class p1, class p2, class p3, class p4, class p5, class p6, class p7, class p8, class p9, class p10>
+ struct find_gather< stream, tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> > {
+ typedef gather::ostream_like::return_tag_holder< tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> , stream > type;
         };
     }
 

Modified: sandbox/logging/boost/logging/detail/format_msg_type.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/format_msg_type.hpp (original)
+++ sandbox/logging/boost/logging/detail/format_msg_type.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -24,7 +24,7 @@
 #include <boost/logging/detail/fwd.hpp>
 #include <boost/logging/detail/find_gather.hpp>
 #include <boost/type_traits/remove_reference.hpp>
-
+#include <boost/logging/detail/tss/tss_ostringstream.hpp>
 
 namespace boost { namespace logging {
 
@@ -42,7 +42,7 @@
 
 namespace destination {
     /**
- @brief what is the default type of your string, in formatter_base ? See BOOST_LOG_DESTINATION_MSG
+ @brief what is the default type of your string, in destination_base ? See BOOST_LOG_DESTINATION_MSG
     */
     template<class T = override> struct msg_type {
         // by default - the default string
@@ -51,6 +51,37 @@
     };
 }
 
+namespace gather {
+ template<class T = override> struct find {
+ template<class msg_type> struct from_msg_type {
+ typedef typename ::boost::logging::detail::find_gather< std::basic_ostringstream<char_type>, msg_type >::type type;
+ };
+ };
+}
+
+
+/**
+ @brief ... just in case you want to specify the ostringstream for the gather class.
+*/
+template<class ostringstream> struct use_ostringstream { };
+
+namespace detail {
+ // gather - if default -> use find_gather< default, default >
+ // - if use_ostringstream -> use find_gather< default, ostringstream>
+ // - else -> use it
+ template<class msg_type, class gather> struct find_gather_from_class {
+ typedef gather type;
+ };
+
+ template<class msg_type> struct find_gather_from_class<msg_type, default_> {
+ typedef typename find_gather< std::basic_ostringstream<char_type>, msg_type >::type type;
+ };
+
+ template<class msg_type, class stream> struct find_gather_from_class<msg_type, use_ostringstream<stream> > {
+ typedef typename find_gather< stream, msg_type >::type type;
+ };
+}
+
 
 /*
     for when compiling fast, and:
@@ -63,7 +94,8 @@
         typedef typename boost::logging::formatter::msg_type<T>::type msg_type_ref;
         typedef typename boost::remove_reference<msg_type_ref>::type msg_type;
 
- typedef typename find_gather< msg_type >::type gather_msg;
+ typedef typename ::boost::logging::gather::find<T>::template from_msg_type<msg_type>::type gather_msg;
+ //typedef typename find_gather< std::basic_ostringstream<char_type>, msg_type >::type gather_msg;
         typedef logger< gather_msg, default_ > log_type;
     };
 

Modified: sandbox/logging/boost/logging/detail/macros.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/macros.hpp (original)
+++ sandbox/logging/boost/logging/detail/macros.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -603,7 +603,7 @@
     template<> struct msg_type<override> { typedef msg_class & type; typedef msg_class raw_type; }; \
     }}}
 
-/**
+/** @section BOOST_LOG_DESTINATION_MSG BOOST_LOG_DESTINATION_MSG
 
 @note
     When using BOOST_LOG_FORMAT_MSG or BOOST_LOG_DESTINATION_MSG, you must not be within any namespace scope.
@@ -617,8 +617,11 @@
     }}}
 
 
-
-
+#define BOOST_LOG_GATHER_CLASS(gather_class) \
+ namespace boost { namespace logging { namespace gather { \
+ template<> struct find<override> { template<class msg_type> struct from_msg_type { \
+ typedef typename ::boost::logging::detail::find_gather_from_class<msg_type, gather_class > ::type type; }; }; \
+ }}}
 
 
 

Modified: sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -1,7 +1,8 @@
 /**
 @page page_changelog Changelog
 
-_at_section changelog_cur_ver Current Version: v0.12.12, 29 dec 2007
+@section changelog_cur_ver Current Version: v0.12.13, 29 dec 2007
+- added tss_ostringstream - allow faster creation of stringstreams (one stringstream per thread)
 - added destination::named - similar to formatter::named_spacer, but for destinations
 - added possibility to flush a rolling file, and fixed a bug
 - added high precision_time tag

Modified: sandbox/logging/boost/logging/detail/raw_doc/todo.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/todo.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/todo.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -125,6 +125,7 @@
 
 - @c normal Explain about config files - you can use named_spacer,named.
 
+- @c normal explain about gather class - how to define (BOOST_LOG_GATHER_CLASS)
 */
 
 }}

Modified: sandbox/logging/boost/logging/detail/ts/ts_resource.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/ts/ts_resource.hpp (original)
+++ sandbox/logging/boost/logging/detail/ts/ts_resource.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -242,13 +242,13 @@
 
     private:
         struct cached_value {
- cached_value(const type & val = type() ) : val(val), is_cached(false) {}
+ cached_value( ) : val( type() ), is_cached(false) {}
             type val;
             bool is_cached;
         };
 
     public:
- tss_resource_once_init(const type& val = type() ) : m_val(val), m_cache(val), m_initialized(false) {}
+ tss_resource_once_init(const type& val = type() ) : m_val(val), m_initialized(false) {}
 
         struct read;
         struct write;

Modified: sandbox/logging/boost/logging/detail/tss/tss.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/tss/tss.hpp (original)
+++ sandbox/logging/boost/logging/detail/tss/tss.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -45,16 +45,40 @@
 
 
 template<class type, template<typename> class thread_specific_ptr_type BOOST_LOG_TSS_DEFAULT_CLASS > struct tss_value {
- tss_value(const type & default_ ) : m_default( default_), m_use_default(true) {}
- tss_value() : m_use_default(false) {}
+ tss_value() {}
 
     type * get() const {
         type * result = m_value.get();
         if ( !result) {
 #if defined(BOOST_LOG_TSS_USE_INTERNAL)
- result = m_use_default ? detail::new_object_ensure_delete<type>(m_default) : detail::new_object_ensure_delete<type>();
+ result = detail::new_object_ensure_delete<type>();
 #else
- result = m_use_default ? (new type(m_default)) : (new type);
+ result = new type;
+#endif
+ m_value.reset( result );
+ }
+ return result;
+ }
+
+ type* operator->() const { return get(); }
+ type& operator*() const { return *get(); }
+private:
+ mutable thread_specific_ptr_type<type> m_value;
+};
+
+
+
+
+template<class type, template<typename> class thread_specific_ptr_type BOOST_LOG_TSS_DEFAULT_CLASS > struct tss_value_with_default {
+ tss_value_with_default(const type & default_ ) : m_default( default_) {}
+
+ type * get() const {
+ type * result = m_value.get();
+ if ( !result) {
+#if defined(BOOST_LOG_TSS_USE_INTERNAL)
+ result = detail::new_object_ensure_delete<type>(m_default) ;
+#else
+ result = new type(m_default);
 #endif
             m_value.reset( result );
         }
@@ -67,10 +91,9 @@
     mutable thread_specific_ptr_type<type> m_value;
     // the default value - to assign each time a new value is created
     type m_default;
- // if true, use default, otherwise not
- bool m_use_default;
 };
 
+
 }}
 
 #endif // !BOOST_LOG_NO_TSS

Added: sandbox/logging/boost/logging/detail/tss/tss_ostringstream.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/tss/tss_ostringstream.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -0,0 +1,68 @@
+// tss_stream.hpp
+
+// Boost Logging library
+//
+// Author: John Torjo, www.torjo.com
+//
+// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+// See http://www.torjo.com/log2/ for more details
+
+
+#ifndef JT28092007_tss_ostringstream_HPP_DEFINED
+#define JT28092007_tss_ostringstream_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/detail/tss/tss.hpp>
+#include <sstream>
+
+namespace boost { namespace logging {
+
+/**
+@brief Represents an ostringstream that takes advantage of TSS (Thread Specific Storage). In other words, each thread has its
+ own copy of an ostringstream, thus when needed, we avoid the cost of re-creating it (it's created only once per thread).
+*/
+template< class stream = std::basic_ostringstream<char_type> > struct tss_ostringstream {
+ typedef stream stream_type;
+ typedef hold_string_type string_type;
+
+ tss_ostringstream() {}
+ tss_ostringstream(const tss_ostringstream&) {}
+
+
+ stream_type & get() {
+ stream_type & val = *(m_cache.get());
+ val.str( BOOST_LOG_STR("") );
+ return val;
+ }
+
+ string_type str() const {
+ stream_type & val = *(m_cache.get());
+ return val.str();
+ }
+
+
+private:
+ mutable tss_value<stream_type> m_cache;
+};
+
+template<class stream, class value_type> inline stream& operator<<( tss_ostringstream<stream> & out, const value_type & val) {
+ stream & result = out.get();
+ result << val;
+ return result;
+}
+
+
+}}
+
+#endif
+

Modified: sandbox/logging/boost/logging/detail/use_format_write.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/use_format_write.hpp (original)
+++ sandbox/logging/boost/logging/detail/use_format_write.hpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -84,6 +84,7 @@
 
 
 
+
 template<
             class format_base_type ,
             class destination_base_type ,
@@ -97,7 +98,7 @@
     typedef typename use_default<lock_resource, ::boost::logging::types<override>::lock_resource> ::type lock_resource_type;
 
     typedef typename format_base::raw_param format_param;
- typedef typename detail::find_gather<format_param>::type gather_type;
+ typedef typename ::boost::logging::gather::find<override>::template from_msg_type<format_param>::type gather_type;
 
     typedef typename detail::find_format_write_params<format_param, format_base, destination_base, lock_resource_type >::apply_format_and_write apply_format_and_write;
     typedef typename detail::find_format_write_params<format_param, format_base, destination_base, lock_resource_type >::router_type router_type;
@@ -117,6 +118,7 @@
 
 @code
 typedef logger_format_write<
+ format_base, destination_base
         gather::ostream_like::return_str<>,
         writer::format_write<formatter_base,destination_base> > > logger_type;
 @endcode
@@ -145,6 +147,8 @@
>::type
>
 {
+ // FIXME we don't use gather - to define the gather class you use BOOST_LOG_GATHER_CLASS
+
     typedef logger<
             typename use_format_write<format_base, destination_base, gather, lock_resource>::gather_type,
             typename detail::find_writer_with_thread_safety<

Modified: sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj
==============================================================================
--- sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj (original)
+++ sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -652,6 +652,10 @@
                                         RelativePath="..\..\..\..\..\boost\logging\detail\tss\tss_impl_win32.hpp"
>
                                 </File>
+ <File
+ RelativePath="..\..\..\..\..\boost\logging\detail\tss\tss_ostringstream.hpp"
+ >
+ </File>
                         </Filter>
                         <Filter
                                 Name="tags"
@@ -834,6 +838,7 @@
>
                                 <FileConfiguration
                                         Name="Test|Win32"
+ ExcludedFromBuild="true"
>
                                         <Tool
                                                 Name="VCCLCompilerTool"
@@ -889,6 +894,10 @@
                                 </FileConfiguration>
                         </File>
                         <File
+ RelativePath="..\..\..\samples\scenarios\use_tss_ostringstream.cpp"
+ >
+ </File>
+ <File
                                 RelativePath="..\..\..\samples\scenarios\using_tags.cpp"
>
                                 <FileConfiguration

Modified: sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp (original)
+++ sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -30,7 +30,7 @@
 
 #include <boost/logging/format.hpp>
 #include <boost/logging/writer/ts_write.hpp>
-#include <boost/logging/format/formatter/high_precision_time.hpp>
+//#include <boost/logging/format/formatter/high_precision_time.hpp>
 #include <boost/logging/format/destination/named.hpp>
 
 using namespace boost::logging;
@@ -55,7 +55,7 @@
     // Step 7: add formatters and destinations
     // That is, how the message is to be formatted...
     g_l->writer().add_formatter( formatter::idx(), "[%] " );
- g_l->writer().add_formatter( formatter::high_precision_time("$hh:$mm:$ss.$mili ") );
+ //g_l->writer().add_formatter( formatter::high_precision_time("$hh:$mm:$ss.$mili ") );
     g_l->writer().add_formatter( formatter::append_newline() );
 
     // ... and where should it be written to

Added: sandbox/logging/lib/logging/samples/scenarios/use_tss_ostringstream.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/scenarios/use_tss_ostringstream.cpp 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -0,0 +1,101 @@
+/**
+@example use_tss_ostringstream.cpp
+
+@copydoc use_tss_ostringstream
+
+@page use_tss_ostringstream use_tss_ostringstream.cpp Example
+
+
+This usage:
+- You have one logger
+- You have one filter, always turned on
+- You want to format the message before it's written
+- The logger has several log destinations
+ - The output goes to console and debug output window
+ - Formatting - prefix each message by its index, and append newline
+
+Optimizations:
+- use tss_ostringstream (each thread has its own ostringstream copy, to make writing faster:
+ when logging of a message, we won't need to create the ostringstream first ; it's created only once per thread )
+- use a cache string (from optimize namespace), in order to make formatting the message faster
+
+
+In this example, all output will be written to the console and debug window.
+It will be:
+
+@code
+[1] this is so cool 1
+[2] this is so cool again 2
+[3] this is too cool 3
+@endcode
+
+*/
+
+
+
+#include <boost/logging/format_fwd.hpp>
+
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
+
+//BOOST_LOG_GATHER_CLASS( use_ostringstream< tss_ostringstream<> > )
+
+ namespace boost { namespace logging { namespace gather {
+ template<> struct find<override> {
+ template<class msg_type> struct from_msg_type {
+ typedef typename ::boost::logging::detail::find_gather_from_class<msg_type, use_ostringstream< tss_ostringstream<> > > ::type type;
+ };
+ };
+ }}}
+
+
+
+#include <boost/logging/format.hpp>
+#include <boost/logging/writer/ts_write.hpp>
+
+using namespace boost::logging;
+
+// Step 3 : Specify your logging class(es)
+typedef logger_format_write< > log_type;
+
+
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
+BOOST_DECLARE_LOG(g_l, log_type)
+
+// Step 5: define the macros through which you'll log
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
+
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
+BOOST_DEFINE_LOG(g_l, log_type)
+
+
+void use_tss_ostringstream_example() {
+ // Step 7: add formatters and destinations
+ // That is, how the message is to be formatted and where should it be written to
+
+ g_l->writer().add_formatter( formatter::idx(), "[%] " );
+ g_l->writer().add_formatter( formatter::append_newline_if_needed() );
+ g_l->writer().add_destination( destination::cout() );
+ g_l->writer().add_destination( destination::dbg_window() );
+
+ // Step 8: use it...
+ int i = 1;
+ L_ << "this is so cool " << i++;
+ L_ << "this is so cool again " << i++;
+ L_ << "this is so too cool " << i++;
+
+ // Step 9 : Enjoy!
+}
+
+
+
+
+int main() {
+ use_tss_ostringstream_example();
+}
+
+
+// End of file
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk