Commit efdf030
perf(fsst): count training candidates by code in flat arrays, not HashMaps (#395)
Counts still tallied candidates with two HashMaps even after #393's
allocation fixes, paying a hash computation, bucket lookup, and
equals() per bump. The Rust reference's Counter (spiraldb/fsst)
counts by code in flat arrays with zero hashing and zero boxing.
Ported the same shape: codes 0..254 are real trained-symbol codes
(resolved through the current Compressor's own symbol table), codes
255..510 are escape pseudo-codes for literal bytes — a fixed,
dense space regardless of how many symbols are actually trained in
any one generation, so counts1/counts2 need no per-generation
resizing. A BitSet per array tracks which slots this generation
touched; only the touched bits are cleared between generations, not
the (much larger) count arrays, mirroring Counter's own
bitmap-gated design. CompressorBuilder now threads one Counts
instance across all five generations of a train() call instead of
allocating fresh ones.
Matcher.longestMatch already returns a code (Matcher.codeOf); this
also fixes the redundancy #393's finding #4 flagged, where that code
was computed and then thrown away in favor of re-deriving an
identity from packed bytes plus length.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P4ijFsGW1MHEcGiu26vNzi1 parent d0e46c3 commit efdf030
2 files changed
Lines changed: 147 additions & 75 deletions
Lines changed: 4 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
64 | 67 | | |
65 | 68 | | |
66 | 69 | | |
67 | 70 | | |
68 | 71 | | |
69 | | - | |
| 72 | + | |
70 | 73 | | |
71 | 74 | | |
72 | 75 | | |
| |||
0 commit comments