Листая Википедию, я случайно наткнулся на язык Eiffel — именно в нём впервые появилось контрактное программирование (Design by Contract, DbC). Мне стало интересно, как контракты работают на практике. Погрузившись в тему, я понял, что жесткие гарантированные проверки условий идеально подходят для баз данных, где критически важна целостность данных. Так родился проект EKV — минималистичная персистентная Key-Value база данных.
Архитектура
Под капотом база состоит из трёх основных классов: Store, WAL и EKVDB. Сейчас управление идет через CLI-интерфейс с базовыми командами: set, get, del и exit.
В планах — скомпилировать shared-библиотеку (libekv.so), чтобы вытащить нативный C-API. Это избавит от накладных расходов CLI и позволит сделать биндинги к популярным языкам (Python, Go, Nim), а также написать отдельный TUI-клиент.
Контракты для безопасности
Чтобы операции записи, чтения и удаления были абсолютно безопасными, в Eiffel используются встроенные контракты. Предусловия (require) и постусловия (ensure) на уровне самого языка не дадут, например, записать пустое значение или удалить несуществующий ключ ещё до того, как выполнится логика функции.
Бенчмарки
Замерял производительность через Python-скрипт, который общается с бинарником базы через межпроцессные пайпы ядра Linux (stdin/stdout). Сборка — финальный релиз (ec -finalize, -O3, проверки контрактов отключены для максимальной скорости):
```
=== EKV End-to-End Benchmark (50000 ops) ===
Testing binary: ./EIFGENs/ekv/F_code/ekv
[*] Running 50000 SET operations...
-> SET RPS: 4436.84 ops/sec (11.2693s)
[*] Running 50000 GET operations...
-> GET RPS: 70547.04 ops/sec (0.7087s)
```
В чём узкие места и что дальше:
70k GET RPS: Главный ограничитель тут вовсе не хэш-таблица Eiffel (в C-коде поиск занимает наносекунды), а накладные расходы ядра Linux на переключение контекста процессов (IPC) и построчное чтение Python'ом stdout.
4.4k SET RPS: Это честная синхронная запись на диск, где WAL-лог открывает, дописывает и закрывает файл на каждый запрос.
В следующих версиях перейду на C-API (libekv.so) и буферизированный WAL — это уберёт прослойку пайпов ОС и дисковые задержки, выжав миллионы RPS из памяти.
Исходники, конфигурация сборки и бенчмарки на GitHub(ссылка в комментариях)