Read the analysis cache before refusing a pass, and own the cache root

Opening a recording while the session that recorded it was still live never reached
``stored_result()``, so the panel reported no result over a recording whose result was on
disk. The guard now follows the cache read, results move to the app's derived-data root
(swept at startup, the old in-recording root ignored), and the panel states which of the
four no-result states it is in, with the pass's own reason.
Verified: apps/studio 462/0/18, shared 431/0/1, autocal 358, ui_check 628/0, both gates
clean, real-GL snapshots per state.
This commit is contained in:
ykcheungab
2026-10-04 16:53:50 +08:00
parent 1aa454311f
commit a92a2ba237
14 changed files with 1138 additions and 170 deletions
+14 -2
View File
@@ -120,8 +120,20 @@ provenance 记 `reference_frame_id`(跟踪器被清空的那一帧)与 `firs
绝不会被默认当作有效结果。一帧的链路调用失败就结束整遍,而不是把过期或空测量写进缓存。
写入分块:帧先攒在内存里,满了整块落到 `frames-*.bin.part` 再原子改名,内存上限是
`chunk_frames × 每帧记录大小`(256 帧约 1.0 MB)。淘汰按明确的容量上限整份删除结果(默认
1 GiB),先删不可用的未完成结果,再按时间从旧到新,永不触碰调用方 `keep` 的那一份。
`chunk_frames × 每帧记录大小`(256 帧约 1.0 MB)。
**缓存根是应用自己的派生数据目录,绝不是录像目录。** 结果写在
`%LOCALAPPDATA%\OrisysStudio\analysis-cache\`(`paths.analysis_cache_dir()`),按**键**分目录;
键与路径无关(`recording_identity` 看会话事实与分段大小,不看目录),所以一份结果对所有副本都
有效 —— 根放在录像里时,只有"恰好写在它旁边的那一份"能找到它,录像换个地方打开就等于没有结果。
写进录像目录还有第二个问题:那是操作员的测量数据,不是应用扔可重建文件的地方。旧的
`for_recording(<recording>/analysis)` 布局**既不读也不迁移**:应用不再往录像里写,也不会去删
操作员的东西,留在那里的结果就是被忽略(重开一次会重跑一遍)。
淘汰与清扫。`evict()` 按容量上限(默认 1 GiB)整份删除:先删不可用的未完成结果,再按时间从旧
到新,永不触碰调用方 `keep` 的那一份。`sweep()` 在启动时给它一个调用点:先清掉**超过宽限期**
(默认 1 h)的未完成结果 —— 默认读端永远拒绝它们,但刚被取消的那一遍是有用的证据,所以先留一
段时间 —— 再按容量上限淘汰。
## 8. 读端