parse_stroke silently dropped digit characters, so number strokes
collapsed onto their letter-only bitmasks: "12K" and "K" both parsed
to K → first-wins dedup let "12K"→"12:00" clobber "K"→"can" (and 297
more core entries: -R→are eaten by 12-R→XII, -S→{^s} by 2-S→2s...).
Digits now map per Plover: 1=S- 2=T- 3=P- 4=H- 5=A- 0=O- 6=-F 7=-P
8=-L 9=-T, all implying #. Collisions: 298 → 0; 300 union keys and
161 translations recovered. Verified: all 262,309 entries byte-exact,
42,000-vector host round trip 0 mismatches.
Spare slots (1.23x) doubled binary size → reverted to v2 (no spare
slots, entry_count == slot_count). CHD now uses entry_count/4
buckets and 1M displacement tries instead of 65K. No trimming.
Removed all trimming/auto-trim logic. Build fails if compiled dict
exceeds flash budget. CHD now uses spare slots (1.23x load factor)
and fewer buckets (entry_count/5) for reliable construction at any
entry count. Binary format bumped to v3: header stores slot_count
and entry_count separately.
Partition: ratio-based split overloaded right side (113K entries →
875KB estimate → heavy trimming to 58K). Now uses 4.5 bytes/entry
from benchmark data → ~34K left, ~113K right, both fit budgets.
CHD: 1:1 bucket ratio (entry_count buckets) prevents hash collision
failures on large partitions. Most buckets have 1 key → trivial
placement. Displacement array grows but still small.
Central has more code overhead (behavior, formatter, output, undo,
BLE client) → smaller dict budget. Peripheral is lean → gets bulk
of dict. Ratio-based partition replaces fixed bytes-per-entry estimate.
Full 147K Plover dict, zero trimming target.
Importance-based partitioning — highest-importance entries on left
(central) for zero-latency local lookup, remainder on right
(peripheral) queried over BLE on miss. Both halves embed their own
MPHF binary. Configurable block size for tighter compression.