cellar

Движок электронной таблицы с собственным языком формул, на чистом Dart. Парсер, граф зависимостей и пересчет ячеек - фундамент того, как работает таблица.

cellar
TL;DR

Движок электронной таблицы на чистом Dart. Под капотом таблица - это граф зависимостей между ячейками: меняете одну, а пересчитать нужно ровно те, что от нее зависят, и в правильном порядке. Плюс собственный язык формул с парсером.

Введение

Визуально таблица - это сетка ячеек, но это иллюзия того, что происходит под капотом. Логически это направленный граф: ячейка с формулой зависит от других ячеек, те - от следующих. Вся инженерия cellar сводится к тому, чтобы пересчитывать этот граф правильно и только в той части, которая действительно этого требует.

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

Электронная таблица - это граф, а не таблица

Когда вы меняете одно значение, вы не можете пересчитать все, потому что это расточительство, и не можете пересчитать в случайном порядке, потому что получите мусор. Нужно тронуть ровно те ячейки, которые зависят от измененной, и сделать это в порядке, в котором каждая считается уже на актуальных данных своих предшественников.

Это сердце cellar и одновременно место, где большие таблицы становятся трудными. Наивное решение, которое после каждого изменения пересчитывает всю сетку, работает на десяти ячейках и умирает на тысяче.

example.cell · bash
A1 = 10
A2 = 20
B1 = SUM(A1:A2)
B2 = B1 * 1.23

Топологический порядок правит всем

Пересчет идет по топологически отсортированному графу зависимостей. Топологическая сортировка расставляет ячейки в таком порядке, что прежде чем вы посчитаете любую из них, все, от чего она зависит, уже готово. Благодаря этому каждая формула видит свежие значения своих источников, а не их прежнюю версию.

Это тот же самый шаблон, который решает корректность систем сборки и бандлеров. Порядок - не деталь, а условие того, что результат вообще имеет смысл.

➜
Совет

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

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

Шаблон, который возвращается везде

Самое интересное в cellar то, что задача таблицы оказывается той же задачей, которую вы встречаете в совершенно других местах. Всюду, где изменение одного значения должно потянуть другие в правильном порядке, сидит граф зависимостей плюс топологическая сортировка.

Тот же механизм в других системах

СистемаГде возвращается граф зависимостей
Электронная таблицапересчет зависимых ячеек
Бандлерыпорядок связывания модулей
Системы сборкипорядок компиляции целей
Реактивные фреймворкиобновление производных значений

Больше проектов

Другие работы из той же категории - посмотрите, как мы решаем похожие задачи.

Есть похожий проект?

Напишите нам - смета бесплатна и приходит в течение часа.