fast_buf\!

This commit is contained in:
gabime 2014-03-20 03:47:57 +02:00
parent d0f3b05f90
commit ba2b6aea25
12 changed files with 75 additions and 55 deletions

View File

@ -15,14 +15,13 @@ using namespace std::chrono;
using namespace c11log;
using namespace utils;
int main(int argc, char* argv[])
{
if(argc || argv) {};
if(argc || argv) {};
auto fsink = std::make_shared<sinks::rotating_file_sink>("log", "txt", 1024*1024*50 , 5, 0);
//auto fsink = std::make_shared<sinks::simple_file_sink>("simplelog", "txt");
//auto fsink = std::make_shared<sinks::simple_file_sink>("simplelog", "txt");
auto null_sink = std::make_shared<sinks::null_sink>();
@ -35,7 +34,7 @@ int main(int argc, char* argv[])
auto start = system_clock::now();
const unsigned int howmany = 3000000;
const unsigned int howmany = 5000000;
for(unsigned int i = 0; i < howmany ; i++)
my_logger.info() << "Hello logger " << i;

View File

@ -6,6 +6,7 @@ namespace c11log
{
typedef std::chrono::system_clock log_clock;
typedef std::pair<const char*, std::size_t> bufpair_t;
namespace level
{

View File

@ -2,8 +2,7 @@
// Faster than ostringstream--returns its string by ref
#include<streambuf>
#include<string>
#include "c11log/details/fast_buf.h"
namespace c11log
{
@ -12,7 +11,7 @@ namespace details
class str_devicebuf:public std::streambuf
{
public:
public:
str_devicebuf() = default;
~str_devicebuf() = default;
@ -21,15 +20,21 @@ public:
str_devicebuf& operator=(const str_devicebuf&) = delete;
str_devicebuf& operator=(str_devicebuf&&) = delete;
/*
const std::string& str_ref() const
{
return _str;
}
*/
bufpair_t buf()
{
return _fastbuf.get();
}
void reset_str()
{
_str.clear();
//_str.clear();
_fastbuf.clear();
}
protected:
@ -38,32 +43,35 @@ protected:
return 0;
}
// copy the give buffer into the accumulated string.
// reserve initially 128 bytes which should be enough for common log lines
std::streamsize xsputn(const char_type* s, std::streamsize count) override
{
if(_str.capacity() < k_initial_reserve)
{
_str.reserve(k_initial_reserve);
}
_str.append(s, static_cast<unsigned int>(count));
// copy the give buffer into the accumulated string.
// reserve initially 128 bytes which should be enough for common log lines
std::streamsize xsputn(const char_type* s, std::streamsize count) override
{
/*
if(_str.capacity() < k_initial_reserve)
{
_str.reserve(k_initial_reserve);
}
_str.append(s, static_cast<unsigned int>(count));
*/
_fastbuf.append(s, static_cast<unsigned int>(count));
return count;
}
int_type overflow(int_type ch) override
{
bool not_eofile = traits_type::not_eof(ch);
bool not_eofile = traits_type::not_eof(ch);
if (not_eofile)
{
char c = traits_type::to_char_type(ch);
{
char c = traits_type::to_char_type(ch);
xsputn(&c, 1);
}
return not_eofile;
}
return not_eofile;
}
private:
std::string _str;
static constexpr std::streamsize k_initial_reserve = 128;
//std::string _str;
fast_buf<128> _fastbuf;
};
class fast_oss:public std::ostream
@ -75,15 +83,21 @@ public:
fast_oss(const fast_oss& other) = delete;
fast_oss(fast_oss&& other) = delete;
fast_oss& operator=(const fast_oss& other) = delete;
/*
const std::string& str_ref() const
{
return _dev.str_ref();
}
void reset_str()
{
_dev.reset_str();
}
*/
bufpair_t buf()
{
return _dev.buf();
}
void reset_str()
{
_dev.reset_str();
}
private:
str_devicebuf _dev;

View File

@ -13,9 +13,9 @@ public:
_flush_every(flush_every),
_write_counter(0) {};
void write(std::ofstream& ofs, const std::string& msg)
void write(std::ofstream& ofs, const bufpair_t& msg)
{
ofs.write(msg.c_str(), msg.size());
ofs.write(msg.first, msg.second);
if(++_write_counter == _flush_every)
{
ofs.flush();

View File

@ -50,7 +50,7 @@ public:
if (_enabled)
{
_oss << os::eol();
_callback_logger->_log_it(_oss.str_ref(), _level);
_callback_logger->_log_it(_oss.buf(), _level);
}
}

View File

@ -50,9 +50,9 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
constexpr inline const char* eol()
{
#ifdef _WIN32
return "\r\n";
return "\r\n";
#else
return "\n";
return "\n";
#endif
}
} //os

View File

@ -88,9 +88,10 @@ inline void c11log::formatters::default_formatter::_format_time(const log_clock:
time_oss << tm_now.tm_sec << ']';
//Cache the resulted string and its size
s_cache_time_t = tp_time_t;
const std::string &s = time_oss.str_ref();
std::memcpy(s_cache_str, s.c_str(), s.size());
s_cache_size = s.size();
//const std::string &s = time_oss.str_ref();
bufpair_t buf = time_oss.buf();
std::memcpy(s_cache_str, buf.first, buf.second);
s_cache_size = buf.second;
}
dest.write(s_cache_str, s_cache_size);
}

View File

@ -21,6 +21,7 @@ namespace c11log
namespace details
{
class line_logger;
template<std::size_t> class fast_buf;
}
@ -67,7 +68,7 @@ private:
sinks_vector_t _sinks;
std::atomic_int _atomic_level;
void _log_it(const std::string& msg, const level::level_enum level);
void _log_it(const bufpair_t& buf, const level::level_enum level);
};
@ -80,6 +81,7 @@ logger& get_logger(const std::string& name);
// Logger inline implementation
//
#include "details/line_logger.h"
#include "details/fast_buf.h"
inline c11log::logger::logger(const std::string& name, formatter_ptr f, sinks_init_list sinks_list) :
@ -145,10 +147,11 @@ inline bool c11log::logger::should_log(c11log::level::level_enum level) const
{
return level >= _atomic_level.load();
}
inline void c11log::logger::_log_it(const std::string& msg, const level::level_enum level)
inline void c11log::logger::_log_it(const bufpair_t& buf, const level::level_enum level)
{
for (auto &sink : _sinks)
sink->log(msg, level);
sink->log(buf, level);
}
// Static factory function

View File

@ -28,7 +28,7 @@ public:
protected:
void _sink_it(const std::string& msg) override;
void _sink_it(const bufpair_t& msg) override;
void _thread_loop();
private:
@ -57,9 +57,10 @@ inline c11log::sinks::async_sink::~async_sink()
{
_shutdown();
}
inline void c11log::sinks::async_sink::_sink_it(const std::string& msg)
inline void c11log::sinks::async_sink::_sink_it(const bufpair_t& msg)
{
_q.push(msg);
std::string s {msg.first, msg.first+msg.second};
_q.push(s);
}
inline void c11log::sinks::async_sink::_thread_loop()
@ -71,9 +72,10 @@ inline void c11log::sinks::async_sink::_thread_loop()
{
if (_q.pop(msg, pop_timeout))
{
bufpair_t buf(msg.data(), msg.size());
for (auto &sink : _sinks)
{
sink->log(msg, static_cast<level::level_enum>(_level.load()));
sink->log(buf, static_cast<level::level_enum>(_level.load()));
if (!_active)
return;
}

View File

@ -22,7 +22,7 @@ public:
base_sink(const base_sink&) = delete;
base_sink& operator=(const base_sink&) = delete;
void log(const std::string &msg, level::level_enum level)
void log(const bufpair_t &msg, level::level_enum level)
{
if (level >= _level)
{
@ -36,14 +36,14 @@ public:
}
protected:
virtual void _sink_it(const std::string& msg) = 0;
virtual void _sink_it(const bufpair_t& msg) = 0;
std::atomic<int> _level {level::INFO};
};
class null_sink:public base_sink
{
protected:
void _sink_it(const std::string& ) override
void _sink_it(const bufpair_t& ) override
{
}
};

View File

@ -19,10 +19,10 @@ public:
virtual ~console_sink() = default;
protected:
virtual void _sink_it(const std::string& msg) override
virtual void _sink_it(const bufpair_t& msg) override
{
std::lock_guard<std::mutex> lock(_mutex);
_ostream << msg;
_ostream.write(msg.first, msg.second);
}
std::ostream& _ostream;

View File

@ -26,7 +26,7 @@ public:
{
}
protected:
void _sink_it(const std::string& msg) override
void _sink_it(const bufpair_t& msg) override
{
std::lock_guard<std::mutex> lock(_mutex);
_flush_helper.write(_ofstream, msg);
@ -59,14 +59,14 @@ public:
}
protected:
void _sink_it(const std::string& msg) override
void _sink_it(const bufpair_t& msg) override
{
std::lock_guard<std::mutex> lock(_mutex);
_current_size += msg.length();
_current_size += msg.second;
if (_current_size > _max_size)
{
_rotate();
_current_size = msg.length();
_current_size = msg.second;
}
_flush_helper.write(_ofstream, msg);
}
@ -132,7 +132,7 @@ public:
}
protected:
void _sink_it(const std::string& msg) override
void _sink_it(const bufpair_t& msg) override
{
std::lock_guard<std::mutex> lock(_mutex);
if (std::chrono::system_clock::now() >= _midnight_tp)