aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2024-12-02 19:58:22 +1100
committerNeil <nyamatongwe@gmail.com>2024-12-02 19:58:22 +1100
commit96a4a55dc33a3d51dc7fe94228f39fcd013124af (patch)
tree22e39d411c14f9d391da197380ee37980fc398ea
parentb3038de3e52df9a5fef52ab3f3a78573d2bf8c1d (diff)
downloadscintilla-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.cxx19
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);