CRDT: Text Buffer
Алгоритм CRDT для совместного текста
Каждый символ получает уникальный id: site
(идентификатор узла) и clock
(локальный счётчик, увеличиваемый после каждой операции), а также parent
— указатель на предыдущий символ.
-
Вставка
parent
ставится на символ перед точкой вставки (null — в начало). Порядок символов задаётся прямым обходом дерева: родители идут раньше потомков. -
Сортировка при одинаковом parent
Сначала по убываниюcounter
, затем поsite
. При вставке перед символом с тем же parent берём егоcounter + 1
. -
Удаление
id символа попадает в множество удалённых (tombstone). Значение можно забыть, но позиция нужна для корректного порядка.
Оптимизации
- Последовательные вставки одного узла объединяются в блок: массовая вставка стоит как одна операция.
- Блоки хранятся в отсортированном массиве; вставка — O(log n) без явного дерева.
- Удаления группируются диапазонами по
site
иclock
.
Плюсы и минусы
- Плюсы: разумный расход памяти, быстрые запросы/обновления.
- Минусы: сложная логика слияния, только рост метаданных, сборка мусора требует координации.
Интерактивный пример
Четыре пира, задержка сети, редактирование кликом. Исходник — crdt-text-buffer.js
.
Полезные ссылки
- josephg.com/blog/crdts-go-brrr/ — эффективная реализация.
- archagon.net/blog/2018/03/24/data-laced-with-history/ — деревья и сборка мусора.