Files
Sprinter-SDCC/applications/Volkov/docs/p15-tree-copy-results.md
T
snark13 8e389c03f8 Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места.

Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
2026-09-10 10:45:30 +03:00

118 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Sprinter Commander: рекурсивный F5 одного каталога 0.2/P15
Дата: 9 сентября 2026 года.
Статус: основной и отрицательные сценарии `PASS` в MAME 0.288 / BIOS 3.06 /
DSS 1.71.57 на HDD `D:`.
## Реализованный контракт
Если в активной панели нет выбранной группы и cursor стоит на обычном
каталоге, F5 рекурсивно создаёт одноимённое дерево в каталоге passive panel:
- обход breadth-first, без рекурсии C-стека;
- каждый файл проходит прежний crash-safe `temp -> commit` и общий 4-КБ
copy-buffer в выделенной странице W3;
- одновременно открыты не более source и temp;
- пустые каталоги создаются;
- existing target не объединяется и не перезаписывается;
- Esc проверяется между каталогами и на каждом 4-КБ шаге файла;
- при cancel/error уже committed-файлы и созданные каталоги остаются, temp
текущего файла удаляется;
- CWD процесса восстанавливается и passive panel перечитывается после
изменения target.
Начиная с P16 выбранные каталоги также добавляются как несколько roots в ту
же очередь. Этот документ фиксирует более узкий single-root срез P15.
## Память обхода
`sc_tree` на время одной операции выделяет одну дополнительную EMM-страницу.
Первые 256 байт сохраняют исходный CWD. Остаток содержит 1008 узлов по 16
байт: `parent index + DOS 8.3 component + depth`. Абсолютный путь строится
перед операцией по цепочке parent; фиксированный предел глубины — 32, а общий
предел пути остаётся 255 символов.
4-КБ данные файла не смешиваются с traversal queue и не размещаются в W2.
W3 отображается только внутри `bank_read/write` и `bank_read_page/
bank_write_page`; вызовы сами восстанавливают прежнюю страницу.
До добавления root проверяется, что каталог passive panel не совпадает с
source root и не лежит внутри него. Это запрещает саморастущее копирование.
## Проверка
Fixture включает пустой каталог, файлы размером 0, 15, 16 и 4097 байт и
цепочку из 16 вложенных уровней. MAME сообщил точный итог:
```text
Tree copied: 4 files; 19 dirs.
```
После выхода source и target извлечены из CHD и сравнены как полные деревья:
```text
PASS: recursive tree copied exactly; depth=16; no temp.
```
Повторный F5 остановился до изменения файлов: DSS вернул `EISDIR` (`errno
15`) для уже существующего target-каталога. Контрольные состояния:
- [source TREE и пустой target](../artifacts/mame-p15/tree-copy/before.png);
- [успех 4 files / 19 dirs](../artifacts/mame-p15/tree-copy/success.png);
- [repeat остановлен на existing target](../artifacts/mame-p15/tree-copy/repeat-existing-target.png);
- [passive panel перечитана](../artifacts/mame-p15/tree-copy/passive-refreshed.png);
- [Esc удалил temp большого файла](../artifacts/mame-p15/tree-copy/cancel-clean.png);
- [target внутри source отклонён до mutation](../artifacts/mame-p15/tree-copy/self-target-refused.png);
- [чистый возврат в DSS](../artifacts/mame-p15/tree-copy/clean-dss-return.png).
Отдельный cancel-fixture начал копирование `BIG.BIN` размером 4 МБ и подал
Esc до commit. Target root остался как определённый частичный результат,
файл и temp отсутствуют, source не изменён:
```text
PASS: tree cancel removed active temp; source intact; no BIG commit.
```
Self-target fixture расположил passive panel в `SOURCE\TREE\INNER`. Операция
остановилась с `errno 14` (`EINVAL` отображается libc на родной DSS
`EUNKOP`) до первого `mkdir`; `INNER` остался пустым:
```text
PASS: target-inside-source refused before mutation.
```
## Компоновка и размер
Конфигурация `--memory big --safe --max-allocs 3000`:
| Область | После P14 | После P15 | Изменение |
|---|---:|---:|---:|
| `_CODE` W2 | 9503 | 9503 | 0 |
| данные W2 | 3268 | 3524 | +256 |
| свободная куча W2 | 2077 | 1821 | -256 |
| BANK1 | 6477 | 9687 | +3210 |
| BANK2 | 13388 | 14547 | +1159 |
| `SPRCMD.EXE` | 43080 | 43080 | 0 |
256 байт W2 — единственный `ffblk_t` traversal engine. Крупная очередь
динамическая и в эти числа не входит. BANK1/BANK2 имеют соответственно 6697
и 1837 байт запаса; межбанковый аудит чист.
## Воспроизведение
```sh
make hdd-p15-tree-copy ALLOCS=3000
tests/run_mame_hdd.sh build/hdd/p15_tree_copy.chd \
tests/mame_p15_tree_copy.lua artifacts/mame-p15/local 60
tests/check_p15_tree_copy_hdd.sh build/hdd/p15_tree_copy.chd
make hdd-p15-tree-cancel hdd-p15-tree-self ALLOCS=3000
tests/run_mame_hdd.sh build/hdd/p15_tree_cancel.chd \
tests/mame_p15_tree_cancel.lua artifacts/mame-p15/cancel 48
tests/check_p15_tree_cancel_hdd.sh build/hdd/p15_tree_cancel.chd
tests/run_mame_hdd.sh build/hdd/p15_tree_self.chd \
tests/mame_p15_tree_self.lua artifacts/mame-p15/self 48
tests/check_p15_tree_self_hdd.sh build/hdd/p15_tree_self.chd
```