aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2025-03-15 23:01:38 -0400
committerStefan Monnier2025-03-15 23:01:38 -0400
commit52879c61e961cac71e7bb0ba12b73f6dd4f28877 (patch)
treeb8f8c7a6157a0c22fe062b2cdc9bab18d5456149
parent856e081809cb0ab9b4a437bc4a04c98b637b00dd (diff)
downloademacs-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.c41
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
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -231,18 +231,30 @@ markers_move_gap_to_charpos (struct Lisp_Markers *t, ptrdiff_t charpos)
231void 231void
232markers_kill (struct Lisp_Markers *t, struct Lisp_Marker *m) 232markers_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;