package chickpeasimport// Atoms is the immutable interned-string table of a snapshot: id -> string// with an O(1) reverse index. Atom 0 is always the empty string (the RCPG// convention: labels, rel types, property keys, and string property values// are all atom ids, and dense string columns encode missing as atom 0).typeAtomsstruct { strings []string index map[string]uint32}// NewAtoms builds the table from an id-ordered string slice. When the slice// contains duplicates, the smallest id wins reverse lookups.func ( []string) *Atoms { := make(map[string]uint32, len())for , := range {if , := []; ! { [] = uint32() } }return &Atoms{strings: , index: }}// Len is the number of atoms.func ( *Atoms) () int {returnlen(.strings)}// Resolve returns the string for an atom id; ok is false when out of range.func ( *Atoms) ( uint32) (string, bool) {ifint() >= len(.strings) {return"", false }return .strings[], true}// ID returns the atom id for a string; ok is false when never interned.func ( *Atoms) ( string) (uint32, bool) { , := .index[]return , }// Strings exposes the id-ordered table (for serialization). Callers must// not mutate it.func ( *Atoms) () []string {return .strings}// Interner is the build-side, thread-safe string interner (the Rust side// uses lasso). The empty string is pre-interned as atom 0, upholding the// RCPG convention from the start.typeInternerstruct { mu sync.RWMutex strings []string index map[string]uint32}// NewInterner returns an interner holding only atom 0 = "".func () *Interner {return &Interner{strings: []string{""},index: map[string]uint32{"": 0}, }}// newInternerFromAtoms seeds a build-side interner with a snapshot's// id-ordered atom table, preserving every atom id exactly -- the keystone of// thawing a snapshot back into a builder. Duplicate strings keep the// smallest id for lookups, matching NewAtoms.func newInternerFromAtoms( *Atoms) *Interner { := make([]string, len(.strings))copy(, .strings)iflen() == 0 { = []string{""} } := make(map[string]uint32, len())for , := range {if , := []; ! { [] = uint32() } }return &Interner{strings: , index: }}// GetOrIntern returns s's atom id, interning it if new.func ( *Interner) ( string) uint32 { .mu.RLock() , := .index[] .mu.RUnlock()if {return } .mu.Lock()defer .mu.Unlock()if , := .index[]; {return } = uint32(len(.strings)) .strings = append(.strings, ) .index[] = return}// Get returns s's atom id without interning; ok is false when unknown.func ( *Interner) ( string) (uint32, bool) { .mu.RLock()defer .mu.RUnlock() , := .index[]return , }// Resolve returns the string for an atom id; ok is false when out of range.func ( *Interner) ( uint32) (string, bool) { .mu.RLock()defer .mu.RUnlock()ifint() >= len(.strings) {return"", false }return .strings[], true}// Len is the number of interned strings (including atom 0).func ( *Interner) () int { .mu.RLock()defer .mu.RUnlock()returnlen(.strings)}// Atoms snapshots the interner into an immutable table.func ( *Interner) () *Atoms { .mu.RLock()defer .mu.RUnlock() := make([]string, len(.strings))copy(, .strings)returnNewAtoms()}
The pages are generated with Goldsv0.8.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.