Kaydet (Commit) 6d006220 authored tarafından Colomban Wendling's avatar Colomban Wendling

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/
üst b07c8b01
......@@ -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);
......
......@@ -20,6 +20,9 @@ private:
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 @@ private:
}
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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment