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