diff options
author | Neil <nyamatongwe@gmail.com> | 2024-12-02 19:58:22 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2024-12-02 19:58:22 +1100 |
commit | 96a4a55dc33a3d51dc7fe94228f39fcd013124af (patch) | |
tree | 22e39d411c14f9d391da197380ee37980fc398ea | |
parent | b3038de3e52df9a5fef52ab3f3a78573d2bf8c1d (diff) | |
download | scintilla-mirror-96a4a55dc33a3d51dc7fe94228f39fcd013124af.tar.gz |
Improve performance of simple case where FillRange just inserts two entries and
does not need to split, merge, or delete runs.
This avoids multiple binary searches and is a significant improvement for
situations such as marking large numbers of search matches in a huge document.
-rw-r--r-- | src/RunStyles.cxx | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/RunStyles.cxx b/src/RunStyles.cxx index b1177f3b7..848670ba9 100644 --- a/src/RunStyles.cxx +++ b/src/RunStyles.cxx @@ -134,7 +134,8 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST return resultNoChange; } DISTANCE runEnd = RunFromPosition(end); - if (styles.ValueAt(runEnd) == value) { + const STYLE valueCurrent = styles.ValueAt(runEnd); + if (valueCurrent == value) { // End already has value so trim range. end = starts.PositionFromPartition(runEnd); if (position >= end) { @@ -143,6 +144,22 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST } fillLength = end - position; } else { + const DISTANCE startRun = starts.PositionFromPartition(runEnd); + if (position > startRun) { + const DISTANCE runNext = runEnd + 1; + const DISTANCE endRun = starts.PositionFromPartition(runNext); + if (end < endRun) { + // New piece is completely inside a run with a different value so its a simple + // insertion of two points [ (position, value), (end, valueCurrent) ] + const DISTANCE range[] { position, end}; + starts.InsertPartitions(runEnd + 1, range, 2); + // Temporary runEndIndex silences non-useful arithmetic overflow warnings + const ptrdiff_t runEndIndex = runEnd; + styles.Insert(runEndIndex + 1, value); + styles.Insert(runEndIndex + 2, valueCurrent); + return { true, position, fillLength }; + } + } runEnd = SplitRun(end); } DISTANCE runStart = RunFromPosition(position); |