// Property, column, rel-property, and atom accessors over a Snapshot.package chickpeasimport ()// Prop reads node's property key, chaining into typed reads:// g.Prop(n, "age").I64Or(0). The zero Prop means absent.func ( *Snapshot) ( NodeID, string) Prop { , := .PropertyKey()if ! {returnProp{} } , := .columns[]if ! {returnProp{} } , := .Get()if ! {returnProp{} }returnProp{g: , v: , ok: true}}// RelProp reads a relationship property by outgoing-CSR position (as// carried by RelRef.Pos) -- the rel analogue of Prop.func ( *Snapshot) ( uint32, string) Prop { , := .PropertyKey()if ! {returnProp{} } , := .relColumns[]if ! {returnProp{} } , := .Get()if ! {returnProp{} }returnProp{g: , v: , ok: true}}// RelEndpoints returns the (source, target) node ids of the rel at// outgoing-CSR position pos -- the tail and head as stored, independent of// the traversal direction that produced the position (backs startNode/// endNode). O(log n): the target indexes outNbrs directly; the source is// the node whose offset range contains pos.func ( *Snapshot) ( uint32) (, NodeID, bool) { := int()if >= len(.outNbrs) {return0, 0, false } = .outNbrs[]// The source is the last node whose CSR range starts at or before pos; // empty ranges share an offset, so a <= partition picks the owner. := sort.Search(len(.outOffsets), func( int) bool { returnint(.outOffsets[]) > })if == 0 {return0, 0, false }returnNodeID( - 1), , true}// RelTypeAt returns the type name of the relationship at outgoing-CSR// position pos (backs the query engine's type(r)). Every relationship has// exactly one type, so ok is a BOUNDS guard only -- false means "pos does// not index a relationship", never "this relationship has no type" -- which// is why it mirrors RelEndpoints rather than the semantically-fallible// RelProp. O(1): a direct index into the outgoing-CSR type array, then the// atom table resolves the id to its interned name.func ( *Snapshot) ( uint32) (string, bool) {ifint() >= len(.outTypes) {return"", false }return .atoms.Resolve(uint32(.outTypes[]))}// Col resolves a reader for the node property key; ok is false when no such// column exists. Narrow with I64/F64/Bool/Str and hoist out of a hot loop// instead of calling Prop per node.func ( *Snapshot) ( string) (Col, bool) { , := .PropertyKey()if ! {returnCol{}, false } , := .columns[]if ! {returnCol{}, false }returnCol{col: }, true}// ColIndexed is Col with O(1) reads at scattered node ids even when the// column is stored sparse: a position -> slot index is built once (lazily,// cached on the snapshot) and shared by every reader. Use in hot kernels// reading a sparse column at many positions; dense columns are already O(1)// and ignore the index.func ( *Snapshot) ( string) (Col, bool) { , := .PropertyKey()if ! {returnCol{}, false } , := .columns[]if ! {returnCol{}, false }returnCol{col: , idx: .posIndexFor(, , &.colPosMu, .colPosIndex)}, true}// RelCol resolves a reader for the relationship property key, indexed by// outgoing-CSR position (see RelRef.Pos); ok is false when absent.func ( *Snapshot) ( string) (Col, bool) { , := .PropertyKey()if ! {returnCol{}, false } , := .relColumns[]if ! {returnCol{}, false }returnCol{col: }, true}// RelColIndexed is RelCol with O(1) sparse reads -- ideal for per-rel// weight reads inside a search.func ( *Snapshot) ( string) (Col, bool) { , := .PropertyKey()if ! {returnCol{}, false } , := .relColumns[]if ! {returnCol{}, false }returnCol{col: , idx: .posIndexFor(, , &.relColPosMu, .relColPosIndex)}, true}// posIndexFor lazily builds (once) and returns the position -> slot index// for a sparse column; dense columns are already O(1) and get nil. The// table is insert-only and an entry, once built, is never replaced, so the// returned map reads safely off-lock.func ( *Snapshot) ( PropertyKey, Column, *sync.Mutex, map[PropertyKey]posIndex) posIndex {if !isSparse() {returnnil } .Lock() , := [] .Unlock()if {return } := buildPosIndex() .Lock()defer .Unlock()if , := []; {return } [] = return}// NodePropertyKeys lists the property keys node carries a value for, in// ascending key order -- the reverse of Prop (backs keys(n)/properties(n)).// Sorted so the enumeration is deterministic.func ( *Snapshot) ( NodeID) []string {var []stringfor , := range .columns {if , := .Get(); {if , := .atoms.Resolve(); { = append(, ) } } }sort.Strings()return}// Version is the snapshot's version string; ok is false when none was set.func ( *Snapshot) () (string, bool) {if .version == nil {return"", false }return *.version, true}// Atoms is the snapshot's interned-string table (atom <-> string in both// directions).func ( *Snapshot) () *Atoms {return .atoms}// ResolveString resolves an atom id to its string; ok is false when out of// range.func ( *Snapshot) ( uint32) (string, bool) {return .atoms.Resolve()}// PropertyKey resolves a property-key name to its atom; ok is false when// the key was never interned.func ( *Snapshot) ( string) (PropertyKey, bool) {return .atoms.ID()}// Label resolves a label name to its atom; ok is false when unknown.func ( *Snapshot) ( string) (Label, bool) { , := .atoms.ID()returnLabel(), }// RelType resolves a relationship-type name to its atom; ok is false when// unknown. Resolve once and pass to MatchType in a hot loop to skip the// per-call string lookup.func ( *Snapshot) ( string) (RelType, bool) { , := .atoms.ID()returnRelType(), }// ValueFromString resolves a string property value to its interned Value;// ok is false when the string was never interned (so no property equals// it).func ( *Snapshot) ( string) (Value, bool) { , := .atoms.ID()returnStrValue(), }
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.