Skip to content

Commit

Permalink
LogWidget: Use FixedSizeQueue for a log messages buffer
Browse files Browse the repository at this point in the history
Messages buffer is intended to be of a fixed capacity (MAX_LOG_LINES),
which cannot be achieved by std::queue unless we manually pop() extra elements.
std::queue uses std::deque internally which most likely results in allocations performed continuously.
FixedSizeQueue keeps a single buffer during its entire lifetime, avoiding any allocations except the ones
performed by stored objects.
  • Loading branch information
CookiePLMonster committed Aug 31, 2019
1 parent b3969e9 commit 6bfa4fa
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 14 deletions.
19 changes: 7 additions & 12 deletions Source/Core/DolphinQt/Config/LogWidget.cpp
Expand Up @@ -19,8 +19,6 @@

// Delay in ms between calls of UpdateLog()
constexpr int UPDATE_LOG_DELAY = 100;
// Maximum number of lines to show in log viewer
constexpr int MAX_LOG_LINES = 5000;
// Maximum lines to process at a time
constexpr size_t MAX_LOG_LINES_TO_UPDATE = 200;
// Timestamp length
Expand Down Expand Up @@ -70,16 +68,13 @@ void LogWidget::UpdateLog()
std::vector<LogEntry> elements_to_push;
{
std::lock_guard lock(m_log_mutex);
if (m_log_queue.empty())
if (m_log_ring_buffer.empty())
return;

elements_to_push.reserve(std::min(MAX_LOG_LINES_TO_UPDATE, m_log_queue.size()));
elements_to_push.reserve(std::min(MAX_LOG_LINES_TO_UPDATE, m_log_ring_buffer.size()));

for (size_t i = 0; !m_log_queue.empty() && i < MAX_LOG_LINES_TO_UPDATE; i++)
{
elements_to_push.push_back(std::move(m_log_queue.front()));
m_log_queue.pop();
}
for (size_t i = 0; !m_log_ring_buffer.empty() && i < MAX_LOG_LINES_TO_UPDATE; i++)
elements_to_push.push_back(std::move(m_log_ring_buffer.pop_front()));
}

for (auto& line : elements_to_push)
Expand Down Expand Up @@ -168,7 +163,7 @@ void LogWidget::ConnectWidgets()
{
connect(m_log_clear, &QPushButton::clicked, [this] {
m_log_text->clear();
m_log_queue = {};
m_log_ring_buffer.clear();
});
connect(m_log_wrap, &QCheckBox::toggled, this, &LogWidget::SaveSettings);
connect(m_log_font, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
Expand Down Expand Up @@ -219,8 +214,8 @@ void LogWidget::Log(LogTypes::LOG_LEVELS level, const char* text)
text_length--;

std::lock_guard lock(m_log_mutex);
m_log_queue.emplace(std::piecewise_construct, std::forward_as_tuple(text, text_length),
std::forward_as_tuple(level));
m_log_ring_buffer.emplace(std::piecewise_construct, std::forward_as_tuple(text, text_length),
std::forward_as_tuple(level));
}

void LogWidget::closeEvent(QCloseEvent*)
Expand Down
7 changes: 5 additions & 2 deletions Source/Core/DolphinQt/Config/LogWidget.h
Expand Up @@ -7,9 +7,9 @@
#include <QDockWidget>

#include <mutex>
#include <queue>
#include <string>

#include "Common/FixedSizeQueue.h"
#include "Common/Logging/LogManager.h"

class QCheckBox;
Expand Down Expand Up @@ -49,6 +49,9 @@ class LogWidget final : public QDockWidget, LogListener

using LogEntry = std::pair<std::string, LogTypes::LOG_LEVELS>;

// Maximum number of lines to show in log viewer
static constexpr int MAX_LOG_LINES = 5000;

std::mutex m_log_mutex;
std::queue<LogEntry> m_log_queue;
FixedSizeQueue<LogEntry, MAX_LOG_LINES> m_log_ring_buffer;
};

0 comments on commit 6bfa4fa

Please sign in to comment.