Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Mon, 27 Feb 2017 13:16:20 UTC Commit: 6d0062201ee2701acceed9af0227c61e9777037d https://github.com/geany/geany/commit/6d0062201ee2701acceed9af0227c61e977703...
Log Message: ----------- Scintilla: speed up converting byte offsets to character offsets
Use a per-line cache to avoid re-computing the offset from the start of the buffer each time. This dramatically speeds up multiple replacements on large files.
X-Scintilla-Bug-ID: https://sourceforge.net/p/scintilla/bugs/1910/
Modified Paths: -------------- scintilla/gtk/ScintillaGTKAccessible.cxx scintilla/gtk/ScintillaGTKAccessible.h
Modified: scintilla/gtk/ScintillaGTKAccessible.cxx 7 lines changed, 7 insertions(+), 0 deletions(-) =================================================================== @@ -856,6 +856,13 @@ void ScintillaGTKAccessible::NotifyReadOnly() { void ScintillaGTKAccessible::Notify(GtkWidget *, gint, SCNotification *nt) { switch (nt->nmhdr.code) { case SCN_MODIFIED: { + if (nt->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { + // invalidate character offset cache if applicable + const Position line = sci->pdoc->LineFromPosition(nt->position); + if (character_offsets.size() > static_cast<size_t>(line + 1)) { + character_offsets.resize(line + 1); + } + } if (nt->modificationType & SC_MOD_INSERTTEXT) { int startChar = CharacterOffsetFromByteOffset(nt->position); int lengthChar = sci->pdoc->CountCharacters(nt->position, nt->position + nt->length);
Modified: scintilla/gtk/ScintillaGTKAccessible.h 16 lines changed, 15 insertions(+), 1 deletions(-) =================================================================== @@ -20,6 +20,9 @@ class ScintillaGTKAccessible { GtkAccessible *accessible; ScintillaGTK *sci;
+ // cache holding character offset for each line start, see CharacterOffsetFromByteOffset() + std::vector<Position> character_offsets; + // cached length of the deletion, in characters (see Notify()) int deletionLengthChar; // local state for comparing @@ -52,7 +55,18 @@ class ScintillaGTKAccessible { }
int CharacterOffsetFromByteOffset(Position byteOffset) { - return sci->pdoc->CountCharacters(0, byteOffset); + const Position line = sci->pdoc->LineFromPosition(byteOffset); + if (character_offsets.size() <= static_cast<size_t>(line)) { + if (character_offsets.empty()) + character_offsets.push_back(0); + for (Position i = character_offsets.size(); i <= line; i++) { + const Position start = sci->pdoc->LineStart(i - 1); + const Position end = sci->pdoc->LineStart(i); + character_offsets.push_back(character_offsets[i - 1] + sci->pdoc->CountCharacters(start, end)); + } + } + const Position lineStart = sci->pdoc->LineStart(line); + return character_offsets[line] + sci->pdoc->CountCharacters(lineStart, byteOffset); }
void CharacterRangeFromByteRange(Position startByte, Position endByte, int *startChar, int *endChar) {
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).