forked from qt-creator/qt-creator
Core: Adapt output window chunk size and queue timer dynamically
If we notice that our formatter takes longer to handle an incoming chunk of output than the amount of time we wait until we handle the next one, then we lower the chunk size and increase the interval. This way, we ensure responsiveness in the presence of excessive output. Task-number: QTCREATORBUG-30135 Change-Id: I1d1e31a7c6f26b50bdc048322e0f7987ddd7b317 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -37,11 +37,15 @@
|
||||
|
||||
#include <numeric>
|
||||
|
||||
const int chunkSize = 10000;
|
||||
|
||||
using namespace Utils;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
const int defaultChunkSize = 10000;
|
||||
const int minChunkSize = 1000;
|
||||
|
||||
const auto defaultInterval = 10ms;
|
||||
const auto maxInterval = 1000ms;
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace Internal {
|
||||
@@ -70,6 +74,7 @@ public:
|
||||
QTextCursor cursor;
|
||||
QString filterText;
|
||||
int lastFilteredBlockNumber = -1;
|
||||
int chunkSize = defaultChunkSize;
|
||||
QPalette originalPalette;
|
||||
OutputWindow::FilterModeFlags filterMode = OutputWindow::FilterModeFlag::Default;
|
||||
int beforeContext = 0;
|
||||
@@ -97,7 +102,7 @@ OutputWindow::OutputWindow(Context context, const Key &settingsKey, QWidget *par
|
||||
d->formatter.setPlainTextEdit(this);
|
||||
|
||||
d->queueTimer.setSingleShot(true);
|
||||
d->queueTimer.setInterval(10ms);
|
||||
d->queueTimer.setInterval(defaultInterval);
|
||||
connect(&d->queueTimer, &QTimer::timeout, this, &OutputWindow::handleNextOutputChunk);
|
||||
|
||||
d->settingsKey = settingsKey;
|
||||
@@ -492,7 +497,7 @@ void OutputWindow::handleNextOutputChunk()
|
||||
|
||||
// We want to break off the chunks along line breaks, if possible.
|
||||
// Otherwise we can get ugly temporary artifacts e.g. for ANSI escape codes.
|
||||
int actualChunkSize = std::min(chunkSize, int(chunk.first.size()));
|
||||
int actualChunkSize = std::min(d->chunkSize, int(chunk.first.size()));
|
||||
const int minEndPos = std::max(0, actualChunkSize - 1000);
|
||||
for (int i = actualChunkSize - 1; i >= minEndPos; --i) {
|
||||
if (chunk.first.at(i) == '\n') {
|
||||
@@ -544,7 +549,13 @@ void OutputWindow::handleOutputChunk(const QString &output, OutputFormat format)
|
||||
}
|
||||
}
|
||||
|
||||
QElapsedTimer formatterTimer;
|
||||
formatterTimer.start();
|
||||
d->formatter.appendMessage(out, format);
|
||||
if (formatterTimer.elapsed() > d->queueTimer.interval()) {
|
||||
d->queueTimer.setInterval(std::min(maxInterval, d->queueTimer.intervalAsDuration() * 2));
|
||||
d->chunkSize = std::max(minChunkSize, d->chunkSize / 2);
|
||||
}
|
||||
|
||||
if (d->scrollToBottom) {
|
||||
if (d->lastMessage.elapsed() < 5) {
|
||||
@@ -659,7 +670,7 @@ void OutputWindow::flush()
|
||||
{
|
||||
const int totalQueuedSize = std::accumulate(d->queuedOutput.cbegin(), d->queuedOutput.cend(), 0,
|
||||
[](int val, const QPair<QString, OutputFormat> &c) { return val + c.first.size(); });
|
||||
if (totalQueuedSize > 5 * chunkSize) {
|
||||
if (totalQueuedSize > 5 * d->chunkSize) {
|
||||
d->flushRequested = true;
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user