File indexing completed on 2024-06-23 05:46:34
0001 /* 0002 SPDX-FileCopyrightText: 2021-2021 Carlos Alves <cbcalves@gmail.com> 0003 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef COMPACTHISTORYSCROLL_H 0009 #define COMPACTHISTORYSCROLL_H 0010 0011 #include "history/HistoryScroll.h" 0012 #include "konsoleprivate_export.h" 0013 #include <deque> 0014 0015 namespace Konsole 0016 { 0017 class KONSOLEPRIVATE_EXPORT CompactHistoryScroll final : public HistoryScroll 0018 { 0019 typedef QVector<Character> TextLine; 0020 0021 public: 0022 explicit CompactHistoryScroll(const unsigned int maxLineCount = 1000); 0023 ~CompactHistoryScroll() override = default; 0024 0025 int getLines() const override; 0026 int getMaxLines() const override; 0027 int getLineLen(const int lineNumber) const override; 0028 void getCells(const int lineNumber, const int startColumn, const int count, Character buffer[]) const override; 0029 bool isWrappedLine(const int lineNumber) const override; 0030 LineProperty getLineProperty(const int lineNumber) const override; 0031 void setLineProperty(const int lineno, LineProperty prop) override; 0032 0033 void addCells(const Character a[], const int count) override; 0034 void addCellsMove(Character a[], const int count) override; 0035 void addLine(const LineProperty lineProperty = LineProperty()) override; 0036 0037 void removeCells() override; 0038 0039 void setMaxNbLines(const int lineCount); 0040 0041 int reflowLines(const int columns, std::map<int, int> *deltas = nullptr) override; 0042 0043 private: 0044 /** 0045 * This is the actual buffer that contains the cells 0046 */ 0047 std::deque<Character> _cells; 0048 0049 /** 0050 * Each entry contains the start of the next line and the current line's 0051 * properties. The start of lines is biased by _indexBias, i.e. an index 0052 * value of _indexBias corresponds to _cells' zero index. 0053 * 0054 * The use of a biased line start means we don't need to traverse the 0055 * vector recalculating line starts when removing lines from the top, and 0056 * also we don't need to traverse the vector to compute the start of a line 0057 * as we would have to do if we stored line lengths. 0058 * 0059 * unsigned int means we're limited in common architectures to 4 million 0060 * characters, but CompactHistoryScroll is limited by the UI to 1_000_000 0061 * lines (see historyLineSpinner in src/widgets/HistorySizeWidget.ui), so 0062 * enough for 1_000_000 lines of an average ~4295 length (and each 0063 * Character takes 16 bytes, so that's 64Gb!). 0064 */ 0065 struct LineData { 0066 unsigned int index; 0067 LineProperty flag; 0068 }; 0069 /** 0070 * This buffer contains the data about each line 0071 * The size of this buffer is the number of lines we have. 0072 */ 0073 std::vector<LineData> _lineDatas; 0074 unsigned int _indexBias = 0; 0075 0076 /** 0077 * Max number of lines we can hold 0078 */ 0079 size_t _maxLineCount; 0080 0081 /** 0082 * Remove @p lines from the "start" of above buffers 0083 */ 0084 void removeLinesFromTop(size_t lines); 0085 0086 inline int lineLen(const int line) const 0087 { 0088 return line == 0 ? _lineDatas.at(0).index - _indexBias : _lineDatas.at(line).index - _lineDatas.at(line - 1).index; 0089 } 0090 0091 /** 0092 * Get the start of @p line in _cells buffer 0093 * 0094 * index actually contains the start of the next line. 0095 */ 0096 inline int startOfLine(const int line) const 0097 { 0098 return line == 0 ? 0 : _lineDatas.at(line - 1).index - _indexBias; 0099 } 0100 }; 0101 0102 } 0103 0104 #endif