6.8 Управление кольцом фиксированного размера объектов

Кольцо (ring) — это структура данных фиксированного размера, которая поддерживает вставку, удаление, вращение и обращение по индексу с модульной индексацией и обходом. Эффективная структура данных кольца реализована пакетом ring. Он предоставляет функции, перечисленные в этом разделе.

Обратите внимание, что несколько колец в Emacs, таких как кольцо отмены (kill ring) и кольцо меток (mark ring), на самом деле реализованы как простые списки, а не с использованием пакета ring; поэтому следующие функции не будут работать с ними.

Функция: make-ring size

Эта функция возвращает новое кольцо, способное хранить size объектов. size должен быть целым числом.

Функция: ring-p object

Эта функция возвращает t, если object является кольцом, и nil в противном случае.

Функция: ring-size ring

Эта функция возвращает максимальную вместимость ring.

Функция: ring-length ring

Эта функция возвращает количество объектов, которые в настоящее время содержит ring. Это значение никогда не превысит значение, возвращенное ring-size.

Функция: ring-elements ring

Эта функция возвращает список объектов в ring в порядке, от самого нового к самому старому.

Функция: ring-copy ring

Эта функция возвращает новое кольцо, которое является копией ring. Новое кольцо содержит те же (eq) объекты, что и ring.

Функция: ring-empty-p ring

Эта функция возвращает t, если ring пуст, и nil в противном случае.

Самый новый элемент в кольце всегда имеет индекс 0. Более высокие индексы соответствуют более старым элементам. Индексы вычисляются по модулю длины кольца. Индекс -1 соответствует самому старому элементу, -2 — следующему по старости и так далее.

Функция: ring-ref ring index

Эта функция возвращает объект в ring, найденный по индексу index. index может быть отрицательным или больше длины кольца. Если ring пуст, ring-ref вызывает ошибку.

Функция: ring-insert ring object

Эта функция вставляет object в ring, делая его самым новым элементом, и возвращает object.

Если кольцо заполнено, вставка удаляет самый старый элемент, чтобы освободить место для нового элемента.

Функция: ring-remove ring &optional index

Удаляет объект из ring и возвращает этот объект. Аргумент index указывает, какой элемент удалить; если он равен nil, это означает удаление самого старого элемента. Если ring пуст, ring-remove вызывает ошибку.

Функция: ring-insert-at-beginning ring object

Эта функция вставляет object в ring, рассматривая его как самый старый элемент. Значение возвращаемого значения не имеет значения.

Если кольцо заполнено, эта функция удаляет самый новый элемент, чтобы освободить место для вставляемого элемента.

Функция: ring-resize ring size

Устанавливает размер ring равным size. Если новый размер меньше, то самые старые элементы в кольце отбрасываются.

Если вы будете внимательны и не превысите размер кольца, вы можете использовать кольцо в качестве очереди "первый пришел — первый ушел" (first-in-first-out). Например:

(let ((fifo (make-ring 5)))
  (mapc (lambda (obj) (ring-insert fifo obj))
        '(0 one "two"))
  (list (ring-remove fifo) t
        (ring-remove fifo) t
        (ring-remove fifo)))
     ⇒ (0 t one t "two")