113 lines
2.9 KiB
C++
113 lines
2.9 KiB
C++
|
||
#include "MemoryLogHandler.hh"
|
||
|
||
#include <mutex>
|
||
|
||
namespace logging {
|
||
|
||
MemoryLogHandler::MemoryLogHandler( StorageManager & mng_, std::pmr::memory_resource * m_r_, std::size_t _capacity ) :
|
||
records( Collection::key_compare(), m_r_ ), storage(mng_), records_capacity(_capacity), records_balance(0), accum_policy(RESTRICTIVE) {}
|
||
|
||
void MemoryLogHandler::publish( const LogRecord & _record ) {
|
||
|
||
/*
|
||
** Ищем место для нового сообщения в контейнере.
|
||
** Если имеется отпарвленный элемент, то мы его замещаем.
|
||
** Если такого не нашлось в очереди, то мы наращиваем длину нашего отрезка памяти.
|
||
*/
|
||
|
||
//std::lock_guard<std::mutex> guard(lock);
|
||
|
||
if( lock.try_lock() ) try {
|
||
|
||
if( records_capacity > records_balance || accum_policy == EXPANSION ) {
|
||
|
||
Collection::iterator queue = records.find( _record.priority() );
|
||
|
||
if( queue == records.end() )
|
||
queue = records.insert(
|
||
std::pair<Collection::key_type, Collection::mapped_type>(
|
||
_record.priority(), Collection::mapped_type( records.get_allocator().resource() )
|
||
)
|
||
).first;
|
||
|
||
RecordData data( records.get_allocator().resource() );
|
||
data.insert( data.begin(), _record.serialize().first, _record.serialize().first + _record.serialize().second );
|
||
|
||
queue->second.push_back( data );
|
||
|
||
++records_balance;
|
||
|
||
}
|
||
|
||
lock.unlock();
|
||
|
||
} catch(...) {
|
||
|
||
lock.unlock();
|
||
throw;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
void MemoryLogHandler::process() {
|
||
|
||
//std::lock_guard<std::mutex> guard(lock);
|
||
|
||
if( lock.try_lock() ) try {
|
||
|
||
//В случае положительного баланса сообщений начинаем линейный поиск подходящего по приоритету.
|
||
if( records_balance ) {
|
||
|
||
Collection::iterator queue = records.begin();
|
||
|
||
while( queue->second.size() == 0 && queue != records.end() )
|
||
++queue;
|
||
|
||
if( queue != records.end() ) {
|
||
|
||
std::pair<const char*, std::size_t> info( &queue->second.front().front(), queue->second.front().size() );
|
||
|
||
if( storage.commit( info.first, info.second ) ) {
|
||
|
||
queue->second.pop_front();
|
||
--records_balance;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
lock.unlock();
|
||
|
||
} catch(...) {
|
||
|
||
lock.unlock();
|
||
throw;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
void MemoryLogHandler::flush() {
|
||
|
||
records.clear();
|
||
storage.flush_local();
|
||
records_balance = 0;
|
||
|
||
}
|
||
|
||
void MemoryLogHandler::set_capacity( std::size_t _capacity ) {
|
||
|
||
records_capacity = _capacity;
|
||
|
||
}
|
||
|
||
void MemoryLogHandler::set_accumulation_policy(ACCUMULATION_POLICY _policy) {
|
||
|
||
accum_policy = _policy;
|
||
|
||
}
|
||
|
||
}
|