Here is a quote from the Elisp documentation about markers:
A “marker” is a Lisp object used to specify a position in a buffer relative to the surrounding text. A marker changes its offset from the beginning of the buffer automatically whenever text is inserted or deleted, so that it stays with the two characters on either side of it.
I am curious how they implement this. It's not obvious how to do this efficiently.
Let's imagine a buffer with 1000 characters in it, so it has 1001 possible positions for point. And there is a marker m1 right after the 500th character:
v---- marker here, at 501st position. [ 1 2 3 4 5 ... 499 500 [m1] 501 .... 998 999 1000 ] Now let's say we insert 10 new characters at position 200, before the marker. If the marker were stored as an integer (501), it would now be invalid. Its value should be 511. One implementation strategy could be to store all the markers in an array, sorted by their position, when text is inserted, you walk through all the markers greater than the insert position and increment their integers. This would be O(N) in the number of buffer markers, so not great if you had a lot of markers in the buffer.
What algorithm and data structure do they use to implement these "moving markers" efficiently?
insertinsrc/insdel:674, insert_1_bothinsrc/insdel.c:884andadjust_markers_for_insertinsrc/insdel.c:288, for one possible path - all line numbers are for upstream sources from May 16 (head commit 650ee9e071eea2ff8504e056131efa9f6ac894e9) - your copy might be slightly different).