summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-09-09 19:06:57 -0400
committerAndreas Kling <kling@serenityos.org>2020-09-10 12:01:26 +0200
commit61060c0da8da19681b9768efbdf467534f70b54a (patch)
treeb087e77102d577e44d9ffa74a92602726edd345b
parent90d9c83067f2a0b1ea576e5e3f995d4f5c5ac72c (diff)
downloadserenity-61060c0da8da19681b9768efbdf467534f70b54a.zip
LibVT: Let Terminal keep history in a circular buffer
This makes Terminal::scroll_up() O(1) instead of O(n) in the size of the history. (It's still O(n) in the size of visible lines.) Reduces time to run `disasm /bin/id` with the default terminal window size from 530ms to 409ms (min-of-5) on my system.
-rw-r--r--Libraries/LibVT/Terminal.cpp6
-rw-r--r--Libraries/LibVT/Terminal.h14
2 files changed, 16 insertions, 4 deletions
diff --git a/Libraries/LibVT/Terminal.cpp b/Libraries/LibVT/Terminal.cpp
index bc49f82562..fd651408d2 100644
--- a/Libraries/LibVT/Terminal.cpp
+++ b/Libraries/LibVT/Terminal.cpp
@@ -52,6 +52,8 @@ void Terminal::clear()
void Terminal::clear_including_history()
{
m_history.clear();
+ m_history_start = 0;
+
clear();
m_client.terminal_history_changed();
@@ -738,9 +740,7 @@ void Terminal::scroll_up()
invalidate_cursor();
if (m_scroll_region_top == 0) {
auto line = move(m_lines.ptr_at(m_scroll_region_top));
- m_history.append(move(line));
- while (m_history.size() > max_history_size())
- m_history.take_first();
+ add_line_to_history(move(line));
m_client.terminal_history_changed();
}
m_lines.remove(m_scroll_region_top);
diff --git a/Libraries/LibVT/Terminal.h b/Libraries/LibVT/Terminal.h
index 49a73fd32e..fb1cea884c 100644
--- a/Libraries/LibVT/Terminal.h
+++ b/Libraries/LibVT/Terminal.h
@@ -76,7 +76,7 @@ public:
Line& line(size_t index)
{
if (index < m_history.size())
- return m_history[index];
+ return m_history[(m_history_start + index) % m_history.size()];
return m_lines[index - m_history.size()];
}
const Line& line(size_t index) const
@@ -154,7 +154,19 @@ private:
TerminalClient& m_client;
+ size_t m_history_start = 0;
NonnullOwnPtrVector<Line> m_history;
+ void add_line_to_history(NonnullOwnPtr<Line>&& line)
+ {
+ if (m_history.size() < max_history_size()) {
+ ASSERT(m_history_start == 0);
+ m_history.append(move(line));
+ return;
+ }
+ m_history.ptr_at(m_history_start) = move(line);
+ m_history_start = (m_history_start + 1) % m_history.size();
+ }
+
NonnullOwnPtrVector<Line> m_lines;
size_t m_scroll_region_top { 0 };