diff options
| author | Stefan Monnier | 2025-03-15 23:01:38 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2025-03-15 23:01:38 -0400 |
| commit | 52879c61e961cac71e7bb0ba12b73f6dd4f28877 (patch) | |
| tree | b8f8c7a6157a0c22fe062b2cdc9bab18d5456149 | |
| parent | 856e081809cb0ab9b4a437bc4a04c98b637b00dd (diff) | |
| download | emacs-scratch/markers-as-gap-array.tar.gz emacs-scratch/markers-as-gap-array.zip | |
src/marker.c (markers_kill, markers_add): Add fast pathsscratch/markers-as-gap-array
| -rw-r--r-- | src/marker.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/marker.c b/src/marker.c index deaab0eea09..75461dbeb8e 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Markers: examining, setting and deleting. | 1 | /* Markers: examining, setting and deleting. |
| 2 | Copyright (C) 1985, 1997-1998, 2001-2024 Free Software Foundation, | 2 | Copyright (C) 1985, 1997-1998, 2001-2025 Free Software Foundation, |
| 3 | Inc. | 3 | Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| @@ -231,18 +231,30 @@ markers_move_gap_to_charpos (struct Lisp_Markers *t, ptrdiff_t charpos) | |||
| 231 | void | 231 | void |
| 232 | markers_kill (struct Lisp_Markers *t, struct Lisp_Marker *m) | 232 | markers_kill (struct Lisp_Markers *t, struct Lisp_Marker *m) |
| 233 | { | 233 | { |
| 234 | m_index_t i = markers_search_marker (t, m); | 234 | m_index_t i; |
| 235 | if (i < t->gap_beg) | 235 | if (t->gap_beg > 0 && t->markers[t->gap_beg - 1] == m) |
| 236 | { | 236 | /* Optimize common case, where we just added this marker. */ |
| 237 | markers_move_gap (t, i + 1); | 237 | i = --t->gap_beg; |
| 238 | eassert (t->gap_beg == i + 1); | 238 | else if (t->gap_end < t->size && t->markers[t->gap_end] == m) |
| 239 | t->gap_beg = i; | 239 | /* Since we add at the beginning of the gap, you might think this case |
| 240 | } | 240 | is less common yet, in practice it seems to happen about as much |
| 241 | as the previous case. */ | ||
| 242 | i = t->gap_end++; | ||
| 241 | else | 243 | else |
| 242 | { | 244 | { |
| 243 | markers_move_gap (t, i); | 245 | i = markers_search_marker (t, m); |
| 244 | eassert (t->gap_end == i); | 246 | if (i < t->gap_beg) |
| 245 | t->gap_end = i + 1; | 247 | { |
| 248 | markers_move_gap (t, i + 1); | ||
| 249 | eassert (t->gap_beg == i + 1); | ||
| 250 | t->gap_beg = i; | ||
| 251 | } | ||
| 252 | else | ||
| 253 | { | ||
| 254 | markers_move_gap (t, i); | ||
| 255 | eassert (t->gap_end == i); | ||
| 256 | t->gap_end = i + 1; | ||
| 257 | } | ||
| 246 | } | 258 | } |
| 247 | eassert (t->markers[i] == m); | 259 | eassert (t->markers[i] == m); |
| 248 | t->markers[i] = NULL; | 260 | t->markers[i] = NULL; |
| @@ -281,7 +293,12 @@ markers_add (struct Lisp_Markers *t, struct Lisp_Marker *m) | |||
| 281 | { | 293 | { |
| 282 | if (t->gap_beg == t->gap_end) | 294 | if (t->gap_beg == t->gap_end) |
| 283 | t = markers_grow (t); | 295 | t = markers_grow (t); |
| 284 | markers_move_gap_to_charpos (t, m->charpos); | 296 | ptrdiff_t charpos = m->charpos; |
| 297 | /* In the vast majority of cases, the gap doesn't need to be moved. */ | ||
| 298 | if ((t->gap_beg > 0 && t->markers[t->gap_beg - 1]->charpos > charpos) | ||
| 299 | || (t->gap_end < t->size && t->markers[t->gap_end]->charpos < charpos)) | ||
| 300 | markers_move_gap_to_charpos (t, charpos); | ||
| 301 | eassert (t->markers[t->gap_beg] == NULL); | ||
| 285 | t->markers[t->gap_beg++] = m; | 302 | t->markers[t->gap_beg++] = m; |
| 286 | markers_sanity_check (t); | 303 | markers_sanity_check (t); |
| 287 | return t; | 304 | return t; |