Installation
[]
= "0.2"
Quick start
use Interner;
let mut interner = new;
// Intern returns a small Copy handle; the same string always returns the same one.
let while_kw = interner.intern;
let for_kw = interner.intern;
assert_eq!;
// Name comparisons are now integer comparisons, not byte walks.
assert_ne!;
// Resolve borrows the original bytes straight out of the store.
assert_eq!;
Folding a token stream down to symbols, so later passes compare integers and a
name in an AST node costs four bytes instead of an owned String:
use ;
let mut interner = new;
let source = ;
let tokens: = source.iter.map.collect;
// The three `x` occurrences collapsed to one symbol.
assert_eq!;
assert_eq!; // let, x, =, +
Features
- Four-byte handle. A
Symbolis aNonZeroU32newtype —Copy, integer equality / ordering / hashing, andOption<Symbol>is four bytes too. - Bytes stored once. Interned strings are appended end to end in a single contiguous buffer; the dedup index stores symbol ids, not a second copy.
- Allocation-free hits. Interning a string already seen is a hash lookup with no allocation and no copy.
- Growth-stable symbols. A symbol keeps resolving to the same string for the interner's whole lifetime, including after the backing store reallocates.
no_std. Relies only onalloc; the defaultstdfeature is additive. No runtime dependencies beyond an optionalserde(planned).#![forbid(unsafe_code)]. The contiguous store is implemented without anyunsafe.
Performance
Resolution is a side-table index plus a slice — measured at roughly 1.1 ns per
resolve (Criterion mean, Windows x86_64, Rust stable, on the development
machine). Interning an already-seen string is allocation-free: a hash over the
bytes, an open-addressing probe, and one byte comparison to confirm the hit. The
numbers below are a v0.x baseline, tracked over time rather than advertised as
final:
| Operation | Mean |
|---|---|
resolve (id → &str) |
~1.1 ns |
intern (repeat hit, no allocation) |
~0.23 µs |
intern (new string, amortised growth) |
~0.62 µs |
Run them yourself with cargo bench.
API overview
For the complete reference with examples, see docs/API.md.
Symbol— four-byteCopyhandle to an interned string.Interner— single-threaded interner:intern,get,resolve,len,with_capacity.
Status
v0.2.0 ships the core interner and symbol. The thread-safe ConcurrentInterner,
optional serde for Symbol, and the defined symbol-space-exhaustion result land
across the remaining 0.x series per the ROADMAP; the public surface freezes at 1.0.0.
Contributing
See dev/DIRECTIVES.md for engineering standards and the definition of done. Before a PR: cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean.