From 39be73514c317e7d672e0a09862571e64f8979da Mon Sep 17 00:00:00 2001 From: Zufu Liu Date: Thu, 15 Jul 2021 17:29:24 +1000 Subject: Feature [feature-requests:#1370] Implement SCI_ALLOCATELINES to allocate indices to hold some number of lines. This is an optimization that can decrease reallocation overhead. --- call/ScintillaCall.cxx | 4 ++++ doc/ScintillaDoc.html | 7 +++++++ doc/ScintillaHistory.html | 5 +++++ include/Scintilla.h | 1 + include/Scintilla.iface | 3 +++ include/ScintillaCall.h | 1 + include/ScintillaMessages.h | 1 + src/CellBuffer.cxx | 23 +++++++++++++++++++++++ src/CellBuffer.h | 1 + src/Document.cxx | 4 ++++ src/Document.h | 1 + src/Editor.cxx | 4 ++++ src/Partitioning.h | 5 +++++ 13 files changed, 60 insertions(+) diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx index f9bffeb64..bec5ccfed 100644 --- a/call/ScintillaCall.cxx +++ b/call/ScintillaCall.cxx @@ -1120,6 +1120,10 @@ Line ScintillaCall::LineCount() { return Call(Message::GetLineCount); } +void ScintillaCall::AllocateLines(Line lines) { + Call(Message::AllocateLines, lines); +} + void ScintillaCall::SetMarginLeft(int pixelWidth) { Call(Message::SetMarginLeft, 0, pixelWidth); } diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 50409c0af..03fe95ea9 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -531,6 +531,7 @@ SCI_GETREADONLY → bool
SCI_GETTEXTRANGE(<unused>, Sci_TextRange *tr) → position
SCI_ALLOCATE(position bytes)
+ SCI_ALLOCATELINES(line lines)
SCI_ADDTEXT(position length, const char *text)
SCI_ADDSTYLEDTEXT(position length, cell *c)
SCI_APPENDTEXT(position length, const char *text)
@@ -645,6 +646,12 @@ Allocate a document buffer large enough to store a given number of bytes. The document will not be made smaller than its current contents.

+

SCI_ALLOCATELINES(line lines)
+ Allocate line indices to match the lines argument. + This is an optimization that can prevent multiple reallocations of the indices as text is inserted + if the application can estimate the number of lines in the document. + The number of lines will not be reduced by this call.

+

SCI_ADDTEXT(position length, const char *text)
This inserts the first length characters from the string text diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index c4cd3132c..f433322ea 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -580,6 +580,11 @@ Feature #1381.

  • + Add SCI_ALLOCATELINES to allocate indices to hold some number of lines. + This can decrease reallocation overhead when the application can count or estimate the number of lines in huge files. + Feature #1370. +
  • +
  • On Win32, when technology is changed, buffering is set to a reasonable value for the technology: on for GDI and off for Direct2D as Direct2D performs its own buffering. Feature #1400. diff --git a/include/Scintilla.h b/include/Scintilla.h index a92b51684..088abc0d8 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -467,6 +467,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_GETFIRSTVISIBLELINE 2152 #define SCI_GETLINE 2153 #define SCI_GETLINECOUNT 2154 +#define SCI_ALLOCATELINES 2089 #define SCI_SETMARGINLEFT 2155 #define SCI_GETMARGINLEFT 2156 #define SCI_SETMARGINRIGHT 2157 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 131ca2814..b59cda663 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1196,6 +1196,9 @@ fun position GetLine=2153(line line, stringresult text) # Returns the number of lines in the document. There is always at least one. get line GetLineCount=2154(,) +# Enlarge the number of lines allocated. +set void AllocateLines=2089(line lines,) + # Sets the size in pixels of the left margin. set void SetMarginLeft=2155(, int pixelWidth) diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h index 778a195d0..e0cfdd052 100644 --- a/include/ScintillaCall.h +++ b/include/ScintillaCall.h @@ -320,6 +320,7 @@ public: Position GetLine(Line line, char *text); std::string GetLine(Line line); Line LineCount(); + void AllocateLines(Line lines); void SetMarginLeft(int pixelWidth); int MarginLeft(); void SetMarginRight(int pixelWidth); diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h index 2d19db1ae..a0c641a39 100644 --- a/include/ScintillaMessages.h +++ b/include/ScintillaMessages.h @@ -255,6 +255,7 @@ enum class Message { GetFirstVisibleLine = 2152, GetLine = 2153, GetLineCount = 2154, + AllocateLines = 2089, SetMarginLeft = 2155, GetMarginLeft = 2156, SetMarginRight = 2157, diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index f02d5348a..d94ffaaea 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -71,6 +71,7 @@ public: virtual void SetLineStart(Sci::Line line, Sci::Position position) noexcept = 0; virtual void RemoveLine(Sci::Line line) = 0; virtual Sci::Line Lines() const noexcept = 0; + virtual void AllocateLines(Sci::Line lines) = 0; virtual Sci::Line LineFromPosition(Sci::Position pos) const noexcept = 0; virtual Sci::Position LineStart(Sci::Line line) const noexcept = 0; virtual void InsertCharacters(Sci::Line line, CountWidths delta) noexcept = 0; @@ -132,6 +133,11 @@ public: const Sci::Position widthCurrent = LineWidth(line); starts.InsertText(static_cast(line), static_cast(width - widthCurrent)); } + void AllocateLines(Sci::Line lines) { + if (lines > starts.Partitions()) { + starts.ReAllocate(lines); + } + } void InsertLines(Sci::Line line, Sci::Line lines) { // Insert multiple lines with each temporarily 1 character wide. // The line widths will be fixed up by later measuring code. @@ -237,6 +243,17 @@ public: Sci::Line Lines() const noexcept override { return static_cast(starts.Partitions()); } + void AllocateLines(Sci::Line lines) override { + if (lines > Lines()) { + starts.ReAllocate(lines); + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { + startsUTF32.AllocateLines(lines); + } + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { + startsUTF16.AllocateLines(lines); + } + } + } Sci::Line LineFromPosition(Sci::Position pos) const noexcept override { return static_cast(starts.PartitionFromPosition(static_cast(pos))); } @@ -789,6 +806,10 @@ Sci::Line CellBuffer::Lines() const noexcept { return plv->Lines(); } +void CellBuffer::AllocateLines(Sci::Line lines) { + plv->AllocateLines(lines); +} + Sci::Position CellBuffer::LineStart(Sci::Line line) const noexcept { if (line < 0) return 0; @@ -903,7 +924,9 @@ bool CellBuffer::UTF8IsCharacterBoundary(Sci::Position position) const { void CellBuffer::ResetLineEnds() { // Reinitialize line data -- too much work to preserve + const Sci::Line lines = plv->Lines(); plv->Init(); + plv->AllocateLines(lines); constexpr Sci::Position position = 0; const Sci::Position length = Length(); diff --git a/src/CellBuffer.h b/src/CellBuffer.h index 637d0a6b5..be7957e99 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -191,6 +191,7 @@ public: void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); Sci::Line Lines() const noexcept; + void AllocateLines(Sci::Line lines); Sci::Position LineStart(Sci::Line line) const noexcept; Sci::Position IndexLineStart(Sci::Line line, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept; Sci::Line LineFromPosition(Sci::Position pos) const noexcept; diff --git a/src/Document.cxx b/src/Document.cxx index 6194f772e..96bee868e 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -2266,6 +2266,10 @@ Sci::Line Document::LinesTotal() const noexcept { return cb.Lines(); } +void Document::AllocateLines(Sci::Line lines) { + cb.AllocateLines(lines); +} + void Document::SetDefaultCharClasses(bool includeWordClass) { charClass.SetDefaultCharClasses(includeWordClass); } diff --git a/src/Document.h b/src/Document.h index fe27f4936..7984ad018 100644 --- a/src/Document.h +++ b/src/Document.h @@ -445,6 +445,7 @@ public: void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); Sci::Line LinesTotal() const noexcept; + void AllocateLines(Sci::Line lines); void SetDefaultCharClasses(bool includeWordClass); void SetCharClasses(const unsigned char *chars, CharacterClass newCharClass); diff --git a/src/Editor.cxx b/src/Editor.cxx index 5a0c153da..db7e2366e 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -5988,6 +5988,10 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { else return pdoc->LinesTotal(); + case Message::AllocateLines: + pdoc->AllocateLines(wParam); + break; + case Message::GetModify: return !pdoc->IsSavePoint(); diff --git a/src/Partitioning.h b/src/Partitioning.h index cf1bb6a7b..efa6bf95e 100644 --- a/src/Partitioning.h +++ b/src/Partitioning.h @@ -110,6 +110,11 @@ public: return static_cast(body->Length())-1; } + void ReAllocate(ptrdiff_t newSize) { + // + 1 accounts for initial element that is always 0. + body->ReAllocate(newSize + 1); + } + T Length() const noexcept { return PositionFromPartition(Partitions()); } -- cgit v1.2.3