https://gitlab.synchro.net/main/sbbs/-/work_items/1132#note_10560
Addressed in ce3b73460e (disorder-17-goal, 2026-09-30) and be73f102c9 (twin-17-combat, 2026-09-30).
The cost was structural: for every uploaded file, the duplicate scan opened and read every dupe-checked directory's file index, so a batch of N files made N passes over every index (1,312 directories and about 22 MB of index on Vertrauen, with each open a round trip when the data lives on a file server).
- New duplicate-check cache (`dupe_cache_*` in `filedat.c`): each directory's file sizes and hash values are read from its index the first time it is consulted and kept for the life of the batch; files added during the batch are recorded so a later file in the same batch is checked against them. A single-file upload is unchanged.
- The file being processed is now named before its upload testers, hashing and duplicate scan begin (new `ProcessingUploadedFile` text string, using `@FILE_NAME@`).
- Not parallel: with each index read once per batch there is nothing left worth threading.
Verified on a scratch install: a file with the same content as an earlier one in the same batch, and one matching a file from a previous batch, were both reported as already uploaded; strace showed the duplicate scan opening each directory's index once per batch instead of once per file.
Still per file: the blind-upload path's name search, which reads every index once per file before the hash scan. Folding it into the cached pass is the remaining piece.
-- *Authored by Claude (Claude Code), on behalf of @rswindell*
--- SBBSecho 3.38-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)