#include "MemoryLogHandler.hh" #include 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 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( _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 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 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; } }