\section{Our technique}
\label{sec-our-technique}

\subsection{Protocols}

Recall from \refSec{sec-introduction} the existence of two nested
control loops, the \emph{inner} control loop in which each iteration
is executing a single edit operation, and the \emph{outer} control
loop for the purpose of updating views.

The inner control loop is catered to by two different protocols; one
containing operations on individual \emph{lines} of items and one
containing operations at the \emph{buffer} level, concerning mainly
the creation and deletion of lines.  While we supply reasonable
implementations of both these protocols, we also allow for
sophisticated clients to substitute specific implementations of each
one.

Although the protocol containing operations one individual lines and
the protocol containing operations at the buffer level are
independent, some high-level operations may involve both protocols
simultaneously.  For example, as mentioned in
\refSec{sec-previous-line-oriented}, deleting a region that spans
several lines may require deleting several lines and editing the two
lines at the beginning and the end of the region.  Deleting a line is
an operation that belongs to the buffer-level protocol, whereas
editing a line is an operation that belongs to the line-level
protocol.

The outer control loop is catered to by the \emph{update protocol}.
This protocol is based on the concept of \emph{time stamps}.  In order
to request an update, client code supplies the time stamp of the
previous similar request in addition to four different functions
(\texttt{sync}, \texttt{skip}, \texttt{modify}, and \texttt{create}).
These functions can be thought of as representing editing operations
on the lines of the buffer.  Our protocol implementation calls these
functions in an order that will update the buffer content from its
previous to its current state.  The implementations of these functions
are supplied by client code according to its own representation of the
buffer content.

Presumably, client code maintains a sequence of lines and some kind of
index into that sequence.  The function \texttt{skip} is called with a
positive integer argument, indicating that client code should
increment the sequence index by that amount.  The function
\texttt{create} is called with a single line as an argument and it
indicates that the line should be inserted at the place indicated by
the sequence index.  The function \texttt{modify} is also called with
a single line as an argument.  If the sequence index does not refer to
the line of the argument, client code must firsts delete lines at the
sequence index until the modified line becomes the one at the index.
The \texttt{sync} function is called with a single unmodified line as
an argument.  It is called after a sequence of calls to the functions
\texttt{modify} and \texttt{create}.  Again, client code responds by
deleting lines until the one passed as an argument become the one at
the sequence index.

There are two main challenges that are addressed by the update
protocol.  The first one is that it has to be efficient when there is
little or no modification to the buffer between two calls to the
\texttt{update} function by client code.  Our protocol handles this
case by calling the \texttt{skip} function with a number of
consecutive unmodified lines, as described above.

The second challenge has to do with deleted lines.  The buffer does
not hold on to deleted lines, but the protocol does not contain a
function for deleting a line.  Instead, it requires the contents of a
line to be joined at the end of the preceding line.  With this
technique, a sequence of deleted lines leaves a trace in the form of
an updated time stamp on the line immediately preceding the sequence
of deleted ones.  The \texttt{sync} operation allows for client code
to be informed about the end of the sequence of deleted lines.

\refFig{fig-external-protocols} illustrates the relationship between
these protocols.

\begin{figure}
\begin{center}
\inputfig{fig-external-protocols.pdf_t}
\end{center}
\caption{\label{fig-external-protocols}
External protocols.}
\end{figure}

The protocols illustrated in \refFig{fig-external-protocols} are
related to one another by the \emph{protocol classes} that they
operate on.  The buffer-edit protocol operates on instances of the
protocol class named \texttt{buffer}.  The line-edit protocol operates
on instances of the two protocol classes \texttt{line} and
\texttt{cursor}.  These protocols are tied together by classes and
other code, serving as \emph{glue} to hold the two protocols together.
\refFig{fig-participation}
illustrates the participation of these protocol classes in the
different protocols, omitting the update protocol.

\begin{figure}
\begin{center}
\inputfig{fig-participation.pdf_t}
\end{center}
\caption{\label{fig-participation}
Participation of classes in protocols.}
\end{figure}

The internal protocol contains generic functions for which methods
must be created that specialize to different \emph{implementations} of
the buffer-edit and the line-edit protocols.  Client code using the
library is not concerned with the existence of the internal protocol.

\subsection{Supplied implementations}

For the \emph{line protocol}, we supply two different implementations,
the \emph{standard line} implementation and the \emph{simple line}
implementation.  Similarly, for the \emph{buffer protocol}, we supply
two different implementations, the \emph{standard buffer} implementation
and the \emph{simple buffer} implementation.

\subsubsection{Simple line implementation}

We supply an implementation, called the \emph{simple line}, for
the line editing protocol.  The main purpose of this implementation is
to serve as a reference for \emph{random tests}.  The idea here is
that the implementation of the simple line is trivial, so that the
correctness of the implementation is mostly obvious from inspecting
the code, and in any case, it is unlikely that a defect in the simple
line and another defect in the standard line will result in the same
external behavior on a large body of randomly generated operations.

In addition to serving as a reference implementation for testing the
standard line, this implementation can also serve as a reference for
programmers who would like to create their own implementation of the
line editing protocol.

The simple line implementation provides a single line abstraction,
implemented as a \commonlisp{} simple vector.  Each editing operation
is implemented as reallocation of a new vector followed by calls to
\texttt{replace} to copy items from the original line content to the
one resulting from the editing operation.  Clearly, this technique is
very inefficient.  For that reason, it is not recommended to use the
simple implementation in client code.

\subsubsection{Standard line implementation}

The standard line implementation is the one that a typical application
would always use, unless an application-specific line implementation
is desired.

To appreciate the design of the standard line, we need to distinguish
between two different \emph{categories} of operations on a line.  We
call these categories \emph{editing operations} and \emph{content
  queries}, respectively.  An editing operation is one in which the
content of the line is modified in some way, and is the result of the
interaction of a user typing text, inserting or removing a
\emph{region} of text, or executing a \emph{keyboard macro} that
results in one or more editing operations.  A content query happens
as a result of an \emph{event loop} or a \emph{command loop} updating
one or more \emph{views} of the content.

A crucial observation related to these categories is that content
queries are the result of \emph{events} (typically, the user typing
text or executing commands).  The frequency of such events is fairly
low, giving us ample time to satisfy such a query.  Editing
operations, on the other hand, can be arbitrarily more frequent,
simply because a single keystroke on the part of the user can trigger
a very large number of editing operations.%
\footnote{It is of course possible to supply \emph{aggregate}
  operations that alleviate the problem of frequent editing
  operations.  In particular, it is possible to supply operations that
  insert a \emph{sequence} of items, and that delete a \emph{region}
  of items.  However, such operations complicate the implementations
  of the protocol.  Worse, there are still cases where many simple
  editing operations need to be executed, in particular as a result of
  executing keyboard macros.}

This implementation supplies two different representations of the line
that we call \emph{open} and \emph{closed} respectively.  A line is
\emph{open} if the last operation on it was an editing operation.  It
is \emph{closed} if the last operation was a content query in the
form of a call to the generic function \texttt{items}.  Accordingly, a
line is changed from being open to being closed whenever there is a
content query, and from closed to open when there is a call to an
editing operation.

A closed line is represented as a \commonlisp{} simple vector.  An
open line is represented as a gap buffer. \seesec{sec-previous-work}
The protocol specifically does not allow for the caller of a content
query to modify the vector returned by the query.  This restriction
allows us to return the same vector each time there is a content
query without any intervening editing operation, thus making it
efficient for views to query closed lines repeatedly.  Similarly,
repeated editing operations maintain the line open, making such a
sequence of operations efficient as well.

Clearly, the typical use case when a user issues keystrokes, each one
resulting in a simple editing operation such as inserting or deleting
an item, followed by an update of one or more views of the buffer
content is not terribly efficient.  The reason for this inefficiency
is that this use case results in a line being alternately opened (as a
result of the editing operation) and closed (as a result of the view
update) for each keystroke.  However, this use case does not have to
be very efficient, again because the costly operations are invoked at
the frequency of the event loop.  The use case for which the standard
line design was optimized is the one where a single keystroke results
in several simple editing operations, i.e., the exact situation in
which performance is crucial.

\subsubsection{Simple buffer implementation}

As with the implementations of the line-edit protocol, we supply an
implementation, called the \emph{simple buffer}, for the buffer
editing protocol as well.  Again, the main purpose of this
implementation is to serve as a reference for \emph{random tests}.  As
with the simple line implementation, the implementation of the simple
buffer is trivial, so that the correctness of the implementation is
mostly obvious from inspecting the code.

The simple buffer implementation represents the buffer as a
\commonlisp{} vector of nodes, where each node contains a line and
time stamps indicating when a line was created and last modified.

\subsubsection{Standard buffer implementation}

The main performance challenge for the buffer implementation is to
obtain acceptable performance in the presence of multiple views (into
a single buffer) that are far apart, and that both issue editing
operations in each interaction.  The typical scenario would be a user
having two views, one close to the beginning of the buffer and one
close to the end of the buffer, while executing a keyboard macro that
deletes from one of the views and inserts into the other.

This time, the performance challenge has to do with the \emph{update
  protocol} rather than with the edit protocols.  A naive buffer
implementation would have to iterate over all the lines each time the
update protocol is invoked.

To obtain reasonable performance in the presence of multiple views,
the standard buffer implementation uses a \emph{splay tree}
\cite{Sleator:1985:SBS:3828.3835} with a node for each line in the
buffer.  A splay tree is a \emph{self-adjusting} binary tree, in that
nodes that are frequently used migrate close to the root of the tree.
Although the typical use of splay trees and other tree types is to
serve as implementations of \emph{dictionaries}, an often overlooked
fact is that all trees can be used to implement \emph{editable
  sequences}; that is how we use the splay tree here.

In addition to containing a reference to the associated line, each
node in the splay tree contains time stamps corresponding to when the
line was created and last modified.  In addition, each node also
contains summary information for the entire subtree rooted at this
node.  This summary information is what allows us to skip entire
subtrees when a view requests update information and no node in the
subtree has been modified since the last update request.

Finally, each node contains both a line count and an item count for
the entire subtree, so that the offset of a particular line or a
particular item can be computed efficiently, at least for nodes that
are close to the root of the tree.
