package chickpeas

Import Path
	github.com/freeeve/gochickpeas (on go.dev)

Dependency Relation
	imports 27 packages, and imported by 6 packages

Involved Source Files aggregate.go Chained n-hop walk-count aggregation: the multi-hop path of Aggregation, which seeds per-node walk multiplicity from the filtered sources and expands hop by hop over the CSR (two dense buffers ping-pong, frontier tracked so clears are O(active)), emitting one row per reached endpoint. Split from aggregate_run.go, which holds the single-scan Run. aggregate_run.go analytics.go atoms.go builder.go builder_read.go col.go column.go Narrow integer-column storage (task 213): values that fit a small byte class after a minimum offset store little-endian deltas at width 1, 2, 4, or 6 instead of 8 bytes each. Narrowing is a storage choice made at column build -- the logical Dtype stays I64 and values read back identically through every class. The 6-byte class exists for epoch-millis timestamp columns, whose offset spans sit at 37-45 bits -- past u32, far under u64. Dense, sparse, and rank layouts share one value-vector representation. column_rank.go cow.go finalize.go fulltext.go geo.go index.go int128.go kernels.go Neighbor-counting and common-neighbor analytics: the neighbor histogram, the pairwise common-neighborhood set, and the masked A^2 / link- prediction primitive (per-source distinct two-hop endpoint counts, folded in parallel). Split from kernels.go, which holds the roots-via / functional-relationship kernels. Label-conditional degree statistics: the average number of relationships of one type, in one direction, per node carrying one label. The global AvgDegree averages a type's count over the type's OWN sources, which says nothing about how a particular label's nodes fan out over it -- a type whose rels overwhelmingly leave one label reads as a huge average for every label that merely touches it. A chain-cost estimator multiplying hop fan-outs needs the conditional form, or a low-cardinality anchor hides an exploding chain behind it. manager.go neighborgroups.go nquads.go N-Quads serialization: writing a snapshot as a deterministic, byte-stable N-Quads document (optionally gzip-compressed), the property Value -> RDF literal mapping, and IRI percent-escaping. Split from nquads.go, which holds the vocabulary, constants, and the parse/build (read) path. prop.go propagate.go propindex.go props.go rangeindex.go removal.go search_bfs.go search_dijkstra.go serialize.go snapshot.go thaw.go traverse.go typedadj.go Bound-pair typed-adjacency queries: counting and position-seeking the m-matched relationships between two given endpoints. Each side-picks the lower-degree endpoint's run (a reverse run lists the same relationships) across the typed-view, below-floor run, and sorted edge-key tiers. Split from typedadj.go, which holds the view construction. Package chickpeas is a high-performance in-memory graph database: the Go implementation of RustyChickpeas. Graphs are built with a Builder, finalized into an immutable read-optimized Snapshot (CSR adjacency, columnar properties, lazy indexes), and exchanged as RCPG files (package rcpg) byte-compatibly with the Rust implementation. value.go
Code Examples package main import ( "fmt" chickpeas "github.com/freeeve/gochickpeas" ) func main() { // Boot: build the initial snapshot and register it. b := chickpeas.NewBuilder(0, 0) alice, _ := b.AddNode("Person") bob, _ := b.AddNode("Person") b.SetProp(alice, "name", "alice") b.SetProp(bob, "name", "bob") b.AddRel(alice, bob, "KNOWS") m := chickpeas.NewManager() m.AddSnapshotWithVersion("v1", b.Finalize()) // One write cycle: read -> thaw -> edit -> Finalize -> swap. cur, _ := m.Snapshot("v1") w := chickpeas.NewBuilderFromSnapshot(cur) carol, _ := w.AddNode("Person") w.SetProp(carol, "name", "carol") w.AddRel(alice, carol, "KNOWS") w.RemoveNode(bob) // detach-delete: bob's rels die with him m.AddSnapshotWithVersion("v2", w.Finalize()) v1, _ := m.Snapshot("v1") v2, _ := m.Snapshot("v2") fmt.Printf("v1: %d nodes, %d rels\n", v1.NodeCount(), v1.RelCount()) fmt.Printf("v2: %d nodes, %d rels\n", v2.NodeCount(), v2.RelCount()) for nbr := range v2.Neighbors(alice, chickpeas.Outgoing) { fmt.Printf("alice now knows %s\n", v2.Prop(nbr, "name").StrOr("?")) } }
Package-Level Type Names (total 48)
/* sort by: | */
AggOp is a comparison operator for Aggregation filters. Test applies the operator. func ParseAggOp(s string) (AggOp, error) func (*Aggregation).Filter(column string, op AggOp, value int64) *Aggregation func (*Aggregation).Having(column string, op AggOp, value int64) *Aggregation const OpEq const OpGe const OpGt const OpLe const OpLt const OpNe
Aggregation is a fluent parallel grouped reduction; build with Snapshot.Aggregate, chain the steps, then Run. Bin groups by a column bucketed at ascending bounds (bucket = count of bounds <= value; field = "{column}_bin"). By groups by an i64 column's value (field = the column name). ByLabel groups by the source node label (key = its index; field "label"). ByLabelMembership groups by membership of one label (key 0/1; field = the label name) -- the n:Label predicate as a dimension, distinct from ByLabel. Filter adds the population predicate `column op value`; rows passing all filters are counted in Total. FilterVia keeps a source node only when column of its projected node (projection[node], e.g. a RootsVia array) is in allowed -- a membership test over any value type, applied with the scalar filters. Having adds a predicate applied to grouped rows only (after the population filters). Hop appends a hop to a chained n-hop WALK count: Run then counts the walks of the whole hop sequence from each filtered source, one group per reachable final endpoint (field "endpoint"). A rel may be reused across hops, so this equals a relationship-unique path count only for shapes where no rel can repeat -- the caller restricts to such shapes. Mutually exclusive with Through. OnlyNeighbors restricts Through counting to these neighbors. RequirePresent keeps only source nodes carrying a value for column (the IS NOT NULL predicate), regardless of dtype. Run executes the reduction in parallel and collects the groups. Sum also sums this i64 column per group. TemporalComponent groups by a temporal component of an epoch-millis column (field = "{column}_{unit}"). Through counts rels of relType/dir out of each filtered source instead of counting nodes, grouping additionally by the neighbor (field "neighbor"); Total still counts source nodes. func (*Aggregation).Bin(column string, bounds ...int64) *Aggregation func (*Aggregation).By(column string) *Aggregation func (*Aggregation).ByLabel() *Aggregation func (*Aggregation).ByLabelMembership(label string) *Aggregation func (*Aggregation).Filter(column string, op AggOp, value int64) *Aggregation func (*Aggregation).FilterVia(projection []NodeID, column string, allowed ...Value) *Aggregation func (*Aggregation).Having(column string, op AggOp, value int64) *Aggregation func (*Aggregation).Hop(relType string, dir Direction) *Aggregation func (*Aggregation).OnlyNeighbors(ids ...NodeID) *Aggregation func (*Aggregation).RequirePresent(column string) *Aggregation func (*Aggregation).Sum(column string) *Aggregation func (*Aggregation).TemporalComponent(column string, unit TemporalUnit) *Aggregation func (*Aggregation).Through(relType string, dir Direction) *Aggregation func (*Snapshot).Aggregate(labels ...string) *Aggregation
AggResult is the outcome of Run. Fields names each key position: "label", a column name, or "{col}_bin" / "{col}_{unit}" / "neighbor" / "endpoint". Rows holds one AggRow per group, unordered. Total counts rows passing the population (Filter) predicates. func (*Aggregation).Run() (*AggResult, error)
AggRow is one output group: the key values in field order (the source label as its index when grouping by label), the row count, and the summed value. Sum is nil exactly when the group's true total lies outside int64 range (the accumulator is 128-bit, so the verdict depends on the total alone, never on how work was partitioned); a query without a Sum column reports 0, not nil. Count uint64 Key []int64 Sum *int64
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). ID returns the atom id for a string; ok is false when never interned. Len is the number of atoms. Resolve returns the string for an atom id; ok is false when out of range. Strings exposes the id-ordered table (for serialization). Callers must not mutate it. func NewAtoms(strings []string) *Atoms func (*Interner).Atoms() *Atoms func (*Snapshot).Atoms() *Atoms
BoolCol is a resolved boolean column reader. Bits is the dense bit vector indexed directly by position; ok is false for a sparse column. Get returns the value at pos; ok is false when absent. func Col.Bool() BoolCol
Builder stages a graph for finalization. AddNode adds a node with an auto-generated sequential id. AddNodeWithID adds (or re-labels) the node with the given id; callers map their own identifiers onto the u32 space. AddRel adds a relationship from u to v, returning its rel index (usable with SetRelPropAt). Endpoints are registered as known nodes. Finalize consumes the builder into an immutable Snapshot; the builder must not be used afterwards. indexProperties optionally names property keys whose (label, key) equality indexes are built upfront (faster first queries, more memory); all others build lazily on first access. A builder thawed from a snapshot rebuilds only the components it dirtied and shares the rest with its source (cow.go), so a property-only edit skips the O(m) CSR rebuild and every untouched column, and the source's lazy caches carry forward. InternPropertyKey interns a property-key name (or any string) and returns its atom, for reuse with SetPropByKey across many rows. NeighborIDs lists node's staged neighbors in direction (outgoing then incoming for Both), skipping removed rels -- an O(rels) pre-finalization scan. NodeCount is the number of distinct nodes staged so far. NodeLabels lists node's staged labels in insertion order. NodesWithProperty lists the label-carrying nodes whose staged property key equals value, in staging order -- an O(pairs) pre-finalization scan. A string value never interned in this builder can't be on any node, so the probe returns empty WITHOUT interning it (reads must not grow the atom table). Prop reads node's staged value for key -- an O(pairs) pre-finalization probe that never interns (a string value never interned can't be staged anywhere). Returns the FIRST staged write, matching the Rust builder. RelCount is the number of live relationships staged so far (tombstoned rels and pending detach-delete cascades excluded). RemoveNode detach-deletes node: its labels and staged properties go immediately, and every currently staged incident rel (with its rel properties) dies at Finalize. Reports whether the node was known. Ids retire rather than reuse -- nextNodeID never rewinds -- but removal is not a permanent tombstone: any later staging touch (AddNodeWithID, SetProp, or being an AddRel endpoint) resurrects the id as a fresh unlabeled, propertyless node. Rels staged before the removal stay dead either way; only rels added after the resurrection survive. RemoveProp deletes node's staged property key, sweeping every staged occurrence across all four typed columns (duplicate staged writes and cross-type stagings all go -- a partial sweep would resurrect a stale value at Finalize). Reports whether anything was removed; false covers every kind of miss uniformly (a key never staged anywhere, or staged but not on this node -- either way no staged pair existed for (node, key)). RemoveRel tombstones the rel at relIdx (as returned by AddRel). The staging array is never compacted -- swap-removal would invalidate every handed-out rel index and the staged rel-prop ids -- so the rel is marked removed, degrees adjust immediately, and Finalize compacts in one pass. Removing a rel that is out of range, already removed, or dead via a detach-deleted endpoint is ErrRelNotFound (no removed bool: a live handle always removes, so removal happened exactly when err is nil). RemoveRelProp deletes the staged property key on the first rel matching (u, v, relType) -- the addressing dual of SetRelProp. For parallel rels, address the specific rel via RemoveRelPropAt. Reports whether anything was removed; an unmatched (u, v, relType) address is ErrRelNotFound. RemoveRelPropAt deletes the staged property key on the rel at relIdx (as returned by AddRel), sweeping every staged occurrence across all four typed columns. Reports whether anything was removed -- a key with no staged pair on this rel is (false, nil), distinguishable from a real removal; a removed or out-of-range rel is ErrRelNotFound. ResolveString resolves an interner atom back to its string (for reading staged Prop values); ok is false when out of range. SetProp stages a node property of any supported type (string, int, int32, int64, float64, bool, or Value), auto-typed into the matching column. The key interns before the value, matching the Rust typed setters' atom order. A key should keep one value type graph-wide: the snapshot stores one column (one dtype) per key, so a key staged under several types across different nodes keeps only one type's column at Finalize -- the other types' pairs are discarded, reported by the snapshot's DroppedCrossTypedStagings (zero on a well-typed graph). Restaging one node's key under a new type is fine via UpdateProp, which sweeps the node's old stagings of every type first. SetPropByKey is SetProp with a pre-interned key (see InternPropertyKey). SetRelProp stages a property on the first rel matching (u, v, relType). For parallel rels (same endpoints and type), address the specific rel by the index AddRel returned via SetRelPropAt. SetRelPropAt stages a property on the rel at the given index (as returned by AddRel). SetVersion sets the snapshot-level version string. UpdateProp replaces node's staged value for key rather than staging a duplicate write, sweeping every prior staged occurrence across all four typed columns so the newest write wins even when it changes the value's type (Finalize's per-type column loops would otherwise resolve a cross-type duplicate by loop order, not write order). func NewBuilder(capNodes, capRels int) *Builder func NewBuilderFromSnapshot(g *Snapshot) *Builder
Col is a resolved property column, narrowed to a typed reader with I64 / F64 / Bool / Str. Build with Snapshot.Col (node columns, indexed by node id) or Snapshot.RelCol (rel columns, indexed by outgoing-CSR position). Bool narrows to a typed boolean reader. Column is the raw generic reader. Dtype is the column's logical element type, for picking a typed reader without narrowing. F64 narrows to a typed float reader. I64 narrows to a typed integer reader; a non-integer column reads back as absent, like a mistyped Prop. Str narrows to a typed string reader exposing interned atom ids; resolve a comparison string to its atom once and compare ids. func (*Snapshot).Col(key string) (Col, bool) func (*Snapshot).ColIndexed(key string) (Col, bool) func (*Snapshot).RelCol(key string) (Col, bool) func (*Snapshot).RelColIndexed(key string) (Col, bool)
Column is one property column's storage. Get reads the value at a position; Entries iterates every (position, value) present, ascending. Concrete representations are internal -- read through Get/Entries or the typed Col readers. Dtype is the column's logical element type. Entries iterates (position, value) pairs in ascending position order. Get returns the value at pos; ok is false when absent. Len is the number of positions carrying a value. func Col.Column() Column
CommonNeighborCount is one (source, target, count) triple of CommonNeighborCounts. Count uint64 Source NodeID Target NodeID func (*Snapshot).CommonNeighborCounts(sources []NodeID, dir Direction, m RelMatch, targets *nodeset.Set) []CommonNeighborCount
CoWeight selects how CoOccurring accumulates each co-occurring node's weight (declarative -- the kernel needs no per-element callback). func CoCount() CoWeight func CoDistinct(key string) CoWeight func (*Snapshot).CoOccurring(seed NodeID, m RelMatch, dir Direction, w CoWeight) map[NodeID]uint64
Direction selects which adjacency a traversal follows. Reverse flips Outgoing and Incoming; Both is its own reverse. String implements fmt.Stringer. Direction : expvar.Var Direction : fmt.Stringer func Direction.Reverse() Direction func ParNeighborFold[T](g *Snapshot, node NodeID, dir Direction, m RelMatch, identity func() T, fold func(acc T, neighbor NodeID) T, reduce func(a, b T) T) T func (*Aggregation).Hop(relType string, dir Direction) *Aggregation func (*Aggregation).Through(relType string, dir Direction) *Aggregation func (*Builder).NeighborIDs(node NodeID, dir Direction) []NodeID func (*Snapshot).AppendNeighborsEach(dst []NodeID, node NodeID, dir Direction, m RelMatch) []NodeID func (*Snapshot).AppendNeighborsMatch(dst []NodeID, node NodeID, dir Direction, m RelMatch) []NodeID func (*Snapshot).AppendRelsBetweenMatch(dst []uint32, u, v NodeID, dir Direction, m RelMatch) []uint32 func (*Snapshot).AvgDegree(relType string, dir Direction) float64 func (*Snapshot).AvgDegreeByLabel(label, relType string, dir Direction) (float64, bool) func (*Snapshot).BFS(start *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set) func (*Snapshot).BFSDistances(start NodeID, dir Direction, m RelMatch, maxDepth int) map[NodeID]uint32 func (*Snapshot).BidirectionalBFS(source, target *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set) func (*Snapshot).CanReach(from, to NodeID, dir Direction, m RelMatch, maxDepth int) bool func (*Snapshot).ChainCollapseVia(relType string, dir Direction, label string) (RootsVia, bool) func (*Snapshot).CommonNeighborCounts(sources []NodeID, dir Direction, m RelMatch, targets *nodeset.Set) []CommonNeighborCount func (*Snapshot).CommonNeighbors(a, b NodeID, dir Direction, m RelMatch) *nodeset.Set func (*Snapshot).CoOccurring(seed NodeID, m RelMatch, dir Direction, w CoWeight) map[NodeID]uint64 func (*Snapshot).CountNeighborsMatch(u, v NodeID, dir Direction, m RelMatch) int func (*Snapshot).Degree(node NodeID, dir Direction) int func (*Snapshot).Dijkstra(source NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).DijkstraTo(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).FirstNeighbor(node NodeID, dir Direction, relTypes ...string) (NodeID, bool) func (*Snapshot).FirstNeighborMatch(node NodeID, dir Direction, m RelMatch) (NodeID, bool) func (*Snapshot).FoldVia(m RelMatch, dir Direction, projection []NodeID) map[NodePair]uint64 func (*Snapshot).FunctionalVia(relType string, dir Direction) bool func (*Snapshot).HasNeighborWithProperty(node NodeID, dir Direction, key string, value any, relTypes ...string) bool func (*Snapshot).HasRel(node NodeID, dir Direction, relTypes ...string) bool func (*Snapshot).NeighborCounts(sources []NodeID, dir Direction, m RelMatch) map[NodeID]int func (*Snapshot).NeighborGroups(sources []NodeID, m RelMatch, dir Direction) *NeighborGroups func (*Snapshot).Neighborhood(seed NodeID, dir Direction, m RelMatch, loHops, hiHops uint32) *nodeset.Set func (*Snapshot).Neighbors(node NodeID, dir Direction, relTypes ...string) iter.Seq[NodeID] func (*Snapshot).NeighborsInSet(node NodeID, dir Direction, set *nodeset.Set, relTypes ...string) iter.Seq[NodeID] func (*Snapshot).NeighborsMatch(node NodeID, dir Direction, m RelMatch) iter.Seq[NodeID] func (*Snapshot).NeighborVia(t RelType, dir Direction) RootsVia func (*Snapshot).Rels(node NodeID, dir Direction, relTypes ...string) iter.Seq[RelRef] func (*Snapshot).RelsMatch(node NodeID, dir Direction, m RelMatch) iter.Seq[RelRef] func (*Snapshot).RootsVia(t RelType, dir Direction) RootsVia func (*Snapshot).RootVia(node NodeID, t RelType, dir Direction) NodeID func (*Snapshot).WCCVia(m RelMatch, dir Direction) []uint32 func (*Snapshot).WeightedShortestPath(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) (float64, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.AppendNeighborsByType(dst []NodeID, node NodeID, dir Direction, types []string) []NodeID func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.AppendNeighborsMatched(dst []NodeID, node NodeID, dir Direction, m *graph.RelMatcher) []NodeID func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.AppendRelationshipsMatched(nodes []NodeID, poss []uint32, node NodeID, dir Direction, m *graph.RelMatcher) ([]NodeID, []uint32) func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.AvgDegree(relType string, dir Direction) float64 func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.AvgDegreeByLabel(label, relType string, dir Direction) (float64, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.ChainRootsVia(types []string, dir Direction, labels []string) (RootsVia, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.CountNeighborsMatched(u, v NodeID, dir Direction, m *graph.RelMatcher) int func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.Degree(node NodeID, dir Direction) int func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.FunctionalVia(types []string, dir Direction) bool func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.Neighbors(node NodeID, dir Direction) iter.Seq[NodeID] func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.NeighborsByType(node NodeID, dir Direction, types []string) iter.Seq[NodeID] func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.NeighborsMatched(node NodeID, dir Direction, m *graph.RelMatcher) iter.Seq[NodeID] func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.Relationships(node NodeID, dir Direction, types []string) iter.Seq2[NodeID, uint32] func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.RelationshipsMatched(node NodeID, dir Direction, m *graph.RelMatcher) iter.Seq2[NodeID, uint32] func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).AppendNeighborsByType(dst []NodeID, node NodeID, dir Direction, types []string) []NodeID func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).AppendNeighborsMatched(dst []NodeID, node NodeID, dir Direction, m *graph.RelMatcher) []NodeID func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).AppendRelationshipsMatched(nodes []NodeID, poss []uint32, node NodeID, dir Direction, m *graph.RelMatcher) ([]NodeID, []uint32) func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).AppendRelsBetween(poss []uint32, u, v NodeID, dir Direction, m *graph.RelMatcher) []uint32 func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).AvgDegree(relType string, dir Direction) float64 func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).AvgDegreeByLabel(label, relType string, dir Direction) (float64, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).ChainRootsVia(types []string, dir Direction, labels []string) (RootsVia, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).CountNeighborsMatched(u, v NodeID, dir Direction, m *graph.RelMatcher) int func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).Degree(node NodeID, dir Direction) int func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).FunctionalVia(types []string, dir Direction) bool func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).Neighbors(node NodeID, dir Direction) iter.Seq[NodeID] func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).NeighborsByType(node NodeID, dir Direction, types []string) iter.Seq[NodeID] func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).NeighborsMatched(node NodeID, dir Direction, m *graph.RelMatcher) iter.Seq[NodeID] func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).Relationships(node NodeID, dir Direction, types []string) iter.Seq2[NodeID, uint32] func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).RelationshipsMatched(node NodeID, dir Direction, m *graph.RelMatcher) iter.Seq2[NodeID, uint32] const Both const Incoming const Outgoing const github.com/freeeve/gochickpeas/gql/internal/graph.Both const github.com/freeeve/gochickpeas/gql/internal/graph.Incoming const github.com/freeeve/gochickpeas/gql/internal/graph.Outgoing
Dtype is the logical element type of a column, reported without narrowing. func Col.Dtype() Dtype func Column.Dtype() Dtype const DtypeBool const DtypeF64 const DtypeI64 const DtypeStr
F64Col is a resolved float column reader. Get returns the value at pos; ok is false when absent. Slice is the dense value slice; ok is false for a sparse column. SliceRange is I64Col.SliceRange for float columns. func Col.F64() F64Col
FullTextField is the inverted index for a single (label, property) text field. Build directly or query through Snapshot.FullTextSearch, which builds and caches per field lazily. DocCount is the number of indexed documents (nodes with non-empty text). Query returns the nodes whose text contains EVERY token in query (boolean AND). An empty query, or any token absent from the field, yields the empty set. QueryRanked returns the top k nodes by BM25 relevance (disjunctive: a node scores for every query token it contains), sorted by score descending, ties by ascending node id. TermCount is the number of distinct indexed tokens. func BuildFullTextField(docs func(yield func(node uint32, text string) bool)) *FullTextField
GeoHit is one KNN result. KM float64 Node uint32 func (*GeoIndex).KNN(lat, lon float64, k int) []GeoHit func (*Snapshot).GeoKNN(label, latKey, lonKey string, lat, lon float64, k int) []GeoHit
GeoIndex is the immutable index for one (label, latKey, lonKey) field. KNN returns up to k nearest nodes to (lat, lon), sorted by increasing distance, ties by ascending node id. Len is the number of indexed points. WithinBBox returns the nodes inside the lat/lon rectangle; minLon > maxLon treats the box as crossing the antimeridian. WithinRadius returns the nodes within km great-circle distance of (lat, lon). func BuildGeoIndex(points func(yield func(node uint32, lat, lon float64) bool)) *GeoIndex
I64Col is a resolved integer column reader. Get returns the value at pos (a node id for node columns, a CSR position for rel columns); ok is false when absent. GetMany reads the values at ids into vals with a presence mask -- the bulk form of Get for candidate-batch sweeps: the representation switch and the receiver hoist out of the loop, so a chunk pays one dispatch instead of a call chain per id. vals and present must be at least len(ids) long. Slice is the dense value slice indexed directly by position; ok is false for a sparse column (fall back to Get). SliceRange is the dense-speed window of a column whose presence is one contiguous position run: values read as vals[pos-start], and a position outside [start, start+len) is absent. LDBC-shaped loaders assign each label a contiguous id block, so a label-scoped column stored sparse still reads at hoisted-slice speed through its window (the rcp twin's as_i64_slice_range, tasks rcp-265/072; a sparse column's pair array is position-sorted, so contiguous presence makes the value array itself the window -- the check is O(1) and nothing is built). ok=false for gapped presence or a non-integer column. func Col.I64() I64Col
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. Atoms snapshots the interner into an immutable table. Get returns s's atom id without interning; ok is false when unknown. GetOrIntern returns s's atom id, interning it if new. Len is the number of interned strings (including atom 0). Resolve returns the string for an atom id; ok is false when out of range. func NewInterner() *Interner
Label is an interned node-label atom. Resolve text via the snapshot. ID is the raw atom id. func (*Snapshot).Label(name string) (Label, bool)
Manager holds named immutable snapshots. AddSnapshot registers g under its own version string, or LatestVersion when it has none, replacing any previous snapshot under that key. AddSnapshotWithVersion registers g under an explicit version key. Clear drops every registered snapshot. Len is the number of registered snapshots. RemoveSnapshot drops the snapshot under version, reporting whether one was present. Snapshot returns the snapshot registered under version; ok is false when absent. Versions lists the registered version keys (unordered). func NewManager() *Manager
NeighborGroups is built by Snapshot.NeighborGroups; chain Project, then call a terminal. Project maps each neighbor to its group node via a chain of first-neighbor steps (like Follow). Without a projection, neighbors group by their own id (every cohort is 1). Sizes is the raw reduction: per source, the size of its largest cohort. Sources with no projectable neighbors yield 0; an unknown rel type or projection type yields all-zero sizes. Runs in parallel over the sources; output order follows the input sources. TopBySize is the n sources with the largest cohorts, size descending. Ties break by the tieKey node property (read as i64, ascending) when non-empty, else by source id ascending -- always deterministic. func (*NeighborGroups).Project(steps ...Step) *NeighborGroups func (*Snapshot).NeighborGroups(sources []NodeID, m RelMatch, dir Direction) *NeighborGroups
NodeFilter gates a node's participation in a search; nil means no filter. func (*Snapshot).BFS(start *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set) func (*Snapshot).BidirectionalBFS(source, target *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set)
NodeID identifies a node. u32 bounds the graph at ~4.3B nodes and keeps roaring bitmaps and CSR arrays compact.
NodePair is an unordered node pair (Lo <= Hi), the key of FoldVia. Hi NodeID Lo NodeID func (*Snapshot).FoldVia(m RelMatch, dir Direction, projection []NodeID) map[NodePair]uint64
Prop is a property read result. The zero value reads as absent: every accessor returns not-ok / its default. Bool returns the boolean value; ok is false when absent or not a boolean. BoolOr returns the boolean value, or def when absent or not a boolean. F64 returns the float value; ok is false when absent or not a float. F64Or returns the float value, or def when absent or not a float. I64 returns the integer value; ok is false when absent or not an integer. I64Or returns the integer value, or def when absent or not an integer. Str returns the string value; ok is false when absent, not a string, or empty (dense string columns store a missing value as "", so the empty check callers would otherwise repeat is folded in). StrOr returns the string value, or def when absent / not a string / empty. Value returns the raw value; ok is false when the property is absent. func (*Snapshot).Prop(node NodeID, key string) Prop func (*Snapshot).RelProp(pos uint32, key string) Prop
PropagateOpts parameterizes PropagateBFS. The zero value is not useful: set RelTypes (empty matches no rels), Direction, MaxDepth, and ValueProp. Desc orders each expansion's eligible rels by ValueProp descending instead of ascending. Ties keep adjacency order (stable). Direction of expansion from each claimed node. FilterMax int64 FilterMin int64 FilterProp, when non-empty, names an integer rel property that must be present and within [FilterMin, FilterMax] for a rel to be eligible at all. MaxDepth bounds the traversal: seeds sit at depth 1 and nodes expand while their depth is below MaxDepth (values below 1 mean seeds only). MinValue is an exclusive lower bound on a claiming rel's carried value; the default 0 propagates only positive values. Pass -Inf to disable. RelTypes is the fan-out union of relationship types. TruncLimit caps each expansion's ordered rels (0 = no cap). ValueProp is the float rel property a claiming rel carries to the node it claims (absent values read as 0). func (*Snapshot).PropagateBFS(seeds []PropagateSeed, opts PropagateOpts) []PropagateResult
PropagateResult is one reached node with its accumulated value and minimum depth (seeds are depth 1). Depth uint32 Node NodeID Value float64 func (*Snapshot).PropagateBFS(seeds []PropagateSeed, opts PropagateOpts) []PropagateResult
PropagateSeed is one traversal start: the node enters at depth 1 carrying Value. The same node may be seeded more than once (one run each). Node NodeID Value float64 func (*Snapshot).PropagateBFS(seeds []PropagateSeed, opts PropagateOpts) []PropagateResult
PropertyKey is an interned property-key atom.
RangeIndex is a sorted view of an i64 node property column: Window answers value intervals with a zero-copy slice of node ids. The zero value is an empty index. Len is the number of indexed entries (nodes carrying the key). Window is the node ids whose value lies in the interval [lo, hi] with per-bound inclusivity, as a zero-copy slice ordered by (value, id). Pass math.MinInt64/math.MaxInt64 with inclusive bounds for a half- or unbounded interval. An empty or inverted interval is an empty slice. func (*Snapshot).ColRangeIndex(key string) (RangeIndex, bool)
RankedHit is one QueryRanked result. Node uint32 Score float32 func (*FullTextField).QueryRanked(query string, k int) []RankedHit func (*Snapshot).FullTextSearchRanked(label, key, query string, k int) []RankedHit
RelFilter gates following a rel, receiving its stored (source, target) endpoints, type, and CSR position; nil means no filter. func (*Snapshot).BFS(start *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set) func (*Snapshot).BidirectionalBFS(source, target *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set)
RelMatch is a resolved relationship-type filter. The common single-type filter matches with one comparison and no allocation; two or more types spill to a slice. Build with Snapshot.Match / MatchType / MatchAll. func MatchAll() RelMatch func MatchNone() RelMatch func MatchType(t RelType) RelMatch func (*Snapshot).Match(relTypes ...string) RelMatch func ParNeighborFold[T](g *Snapshot, node NodeID, dir Direction, m RelMatch, identity func() T, fold func(acc T, neighbor NodeID) T, reduce func(a, b T) T) T func (*Snapshot).AppendNeighborsEach(dst []NodeID, node NodeID, dir Direction, m RelMatch) []NodeID func (*Snapshot).AppendNeighborsMatch(dst []NodeID, node NodeID, dir Direction, m RelMatch) []NodeID func (*Snapshot).AppendRelsBetweenMatch(dst []uint32, u, v NodeID, dir Direction, m RelMatch) []uint32 func (*Snapshot).BFS(start *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set) func (*Snapshot).BFSDistances(start NodeID, dir Direction, m RelMatch, maxDepth int) map[NodeID]uint32 func (*Snapshot).BidirectionalBFS(source, target *nodeset.Set, dir Direction, m RelMatch, nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set) func (*Snapshot).CanReach(from, to NodeID, dir Direction, m RelMatch, maxDepth int) bool func (*Snapshot).CommonNeighborCounts(sources []NodeID, dir Direction, m RelMatch, targets *nodeset.Set) []CommonNeighborCount func (*Snapshot).CommonNeighbors(a, b NodeID, dir Direction, m RelMatch) *nodeset.Set func (*Snapshot).CoOccurring(seed NodeID, m RelMatch, dir Direction, w CoWeight) map[NodeID]uint64 func (*Snapshot).CountNeighborsMatch(u, v NodeID, dir Direction, m RelMatch) int func (*Snapshot).Dijkstra(source NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).DijkstraTo(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).FirstNeighborMatch(node NodeID, dir Direction, m RelMatch) (NodeID, bool) func (*Snapshot).FoldVia(m RelMatch, dir Direction, projection []NodeID) map[NodePair]uint64 func (*Snapshot).NeighborCounts(sources []NodeID, dir Direction, m RelMatch) map[NodeID]int func (*Snapshot).NeighborGroups(sources []NodeID, m RelMatch, dir Direction) *NeighborGroups func (*Snapshot).Neighborhood(seed NodeID, dir Direction, m RelMatch, loHops, hiHops uint32) *nodeset.Set func (*Snapshot).NeighborsMatch(node NodeID, dir Direction, m RelMatch) iter.Seq[NodeID] func (*Snapshot).RelsMatch(node NodeID, dir Direction, m RelMatch) iter.Seq[RelRef] func (*Snapshot).WCCVia(m RelMatch, dir Direction) []uint32 func (*Snapshot).WeightedShortestPath(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) (float64, bool)
RelRef is one relationship incident to a queried node, as yielded by Snapshot.Rels. It carries the other endpoint, the type, the direction relative to the queried node, and the CSR position for reading the rel's properties via Snapshot.RelProp -- valid in BOTH directions (an incoming rel's position is pre-mapped to where the property is stored). Direction Direction Neighbor NodeID Pos uint32 Type RelType
RelStats is the per-type relationship statistics entry: total count and the distinct source/target node counts -- the degree facts a cost-based planner needs. Count is the total rels of this type. InSources is the distinct nodes that are the target of such a rel (the source when traversed incoming). OutSources is the distinct nodes that are the source of such a rel. func (*Snapshot).RelTypeStats(relType string) (RelStats, bool)
RelType is an interned relationship-type atom. Resolve text via the snapshot. ID is the raw atom id. func (*Snapshot).RelType(name string) (RelType, bool) func MatchType(t RelType) RelMatch func (*Snapshot).NeighborVia(t RelType, dir Direction) RootsVia func (*Snapshot).RootsVia(t RelType, dir Direction) RootsVia func (*Snapshot).RootVia(node NodeID, t RelType, dir Direction) NodeID
RelTypeCountEntry pairs a relationship type name with its total count. Count uint64 Type string func (*Snapshot).RelCountByType() []RelTypeCountEntry
RootsVia is a built forest-root array: index it by node id for the terminal of that node's functional-relationship chain. Shared and immutable -- hot loops hold it and index lock-free. func (*Snapshot).ChainCollapseVia(relType string, dir Direction, label string) (RootsVia, bool) func (*Snapshot).NeighborVia(t RelType, dir Direction) RootsVia func (*Snapshot).RootsVia(t RelType, dir Direction) RootsVia func github.com/freeeve/gochickpeas/gql/internal/graph.Graph.ChainRootsVia(types []string, dir Direction, labels []string) (RootsVia, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).ChainRootsVia(types []string, dir Direction, labels []string) (RootsVia, bool)
ShortestPaths is the result of a Dijkstra search: the shortest distance to every reached node, with predecessors for path reconstruction. Small searches keep map state; a search that settles a large set switches to dense id-space arrays mid-run (see densify), so point queries stay cheap while component-scale searches avoid per-edge map probes. Distance is the shortest distance from the source to node; ok is false when unreached. Distances is every reached node with its shortest distance (the source itself at 0). The returned map is the result's own -- callers must not mutate it while still using PathTo. PathTo is the shortest path from the source to target as a node sequence (source first); ok is false when target was unreached. Reached reports whether node was reached from the source. func (*Snapshot).Dijkstra(source NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).DijkstraTo(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths
Snapshot is an immutable graph optimized for read-only queries. The full read surface is deliberately methods on *Snapshot (never free functions), so a future cypher package can capture it in a consumer-side interface. Aggregate starts a parallel grouped reduction over the given labels. AppendNeighborsEach appends one entry per matching dir relationship of node, in CSR order -- the traversal primitive behind pattern expansion, where relationship multiplicity and first-seen order are semantic. It walks the CSR ranges directly rather than through a yield closure: neighborsYield is too large to inline, so handing it a closure would heap-escape that closure on every call. The walk mirrors neighborsYield exactly, minus the early-stop the fill never needs. AppendNeighborsMatch appends node's matching dir neighbors to dst as a deduplicated ASCENDING id set -- the neighbor-ID surface contract (parallel same-type rels, or a rel seen from both directions under Both, contribute one entry). Per-relationship multiplicity in CSR order stays available on AppendNeighborsEach and the Rels iterators. Only the appended tail is sorted and compacted; dst's existing prefix is untouched. AppendRelsBetweenMatch appends the stored CSR position of each m-matched dir relationship between u and v to dst, preserving parallel-relationship multiplicity -- the bound-both-endpoints position seek behind a named-rel rebind expand. Like CountNeighborsMatch it scans whichever endpoint's run is shorter (v's reverse run lists the same relationships as u's forward run), so the cost is the smaller endpoint's degree rather than always the from-side's full degree. Positions come out in the stored (outgoing) frame regardless of which side was scanned, so a subsequent property read by position is correct. Each direction's appended segment is sorted ascending, matching the forward-scan emission order so the seek is order-identical to the enumerate-and-filter path. Atoms is the snapshot's interned-string table (atom <-> string in both directions). AvgDegree is the average fan-out of relType traversed in dir: total such rels divided by the distinct nodes having one in that direction (the degree-by-type-and-direction a cost-based planner needs). 0 for an absent type; Both averages over the nodes touching the type on either side. AvgDegreeByLabel is AvgDegree conditioned on the node's label: the average number of relType relationships in dir per node carrying label, zero-degree members included. ok is false for an unknown or empty label (the caller falls back to the global statistic); a known label with no such rels answers (0, true) -- a real "this hop never fires" fact, not a missing statistic. Both averages the two directions' counts together. BFS traverses from the start set over the m-matched rels in dir, returning every node visited and every rel CSR position traversed. Filters gate participation (nil = none); maxDepth bounds the hop count (NoMaxDepth = unbounded). BFSDistances is unweighted single-source BFS returning the hop distance from start to every reached node (start itself at 0), bounded by maxDepth (NoMaxDepth = the whole component). Cheaper than Dijkstra with a unit weight when only hop counts are needed. BidirectionalBFS searches from the source and target sets simultaneously, meeting in the middle: the forward pass follows dir, the backward pass its reverse. Returns the nodes reached by BOTH sides (the meeting set) and the union of rel positions either side traversed; both empty when the sets don't connect. An immediate source/target overlap returns it with no rels. CDLP is community detection by synchronous label propagation: L0(v) = v, then each node adopts the most frequent label among its neighbors (in+out tallied separately for directed graphs, so a mutual rel counts twice), smallest label breaking ties; a node with no neighbors keeps its label. CDLPSeeded is CDLP with explicit initial labels (init[node] = L0(node)); seed with original vertex ids to match a vertex-id-keyed reference. Missing slots (a short init) default to the node's own id. CSRIDSpace is the number of id slots in 0..=maxNodeID. Dense scratch arrays indexed by raw node id, and loops visiting every source node, must size by this -- not NodeCount, which excludes gaps under sparse ids. CanReach reports whether to is reachable from from over the m-matched rels in dir, within maxDepth hops (NoMaxDepth = unbounded). ChainCollapseVia reports whether an unbounded zero-minimum reachable-set expansion over relType in dir, filtered to label, is equivalent to one RootsVia lookup -- and returns the root array when it is. Two structural facts, each verified (never assumed) and cached: the type must be FUNCTIONAL in dir (every node has at most one such rel, so the reachable set is exactly the ancestor chain), and label must be TERMINAL-EXCLUSIVE for it (no labeled node has such a rel outgoing in dir, so only a chain's terminal can carry the label -- making "reachable nodes with the label" either the root or nothing). CoOccurring is seeded co-occurrence -- one-mode projection by shared neighbor: from seed over the m-matched rels, the nodes sharing a neighbor with seed (seed -(m,dir)-> centers -(m,reversed)-> others), seed itself excluded, each weighted per w. The seeded row of the node-node co-occurrence matrix; the by-shared-neighbor complement of FoldVia's by-rel-endpoint projection. 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. 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. ColRangeIndex resolves the sorted range view for a node property key, building it on first use and caching it on the snapshot for the snapshot's lifetime (the posIndex/LabelDense policy: memory stays proportional to the column's entry count, ~12 bytes each). ok is false when the key has no node column or the column is not i64. (*Snapshot) CommonNeighborCounts(sources []NodeID, dir Direction, m RelMatch, targets *nodeset.Set) []CommonNeighborCount CommonNeighbors is N(a) ∩ N(b) over the m-matched rels in dir (Both gives the undirected common neighborhood) -- the link-prediction primitive, returned as a set so it composes with And/Or/AndNot. CountNeighborsMatch counts the m-matched dir relationships from u to v -- the bound-both-endpoints existence/multiplicity probe. Each direction scans the lower-degree endpoint's run (v's reverse run lists the same relationships), through the typed view when one exists; result multiset cardinality is identical to filtering an enumeration. Degree is the number of relationships incident to node in direction, any type -- an O(1) offset difference per side (Both sums the two). A runtime fan-out signal for adaptive anchor decisions; for a type-restricted count, count Neighbors instead. Dijkstra runs weighted single-source shortest paths from source over the m-matched rels in dir, reaching the whole component. DijkstraTo is Dijkstra stopping as soon as target's shortest distance is known -- the single-pair form; the result still answers every node settled before the stop. DroppedCrossTypedStagings reports how many staged property pairs (node and relationship) Finalize discarded because their key was staged under more than one value type. The snapshot stores one column (one dtype) per key, so a key staged as, say, int64 on some nodes and float64 on others keeps only one type's pairs; the rest vanish with no error from SetProp. Zero means every staged pair is visible. The count is diagnostic only -- the accepted inputs are unchanged. FirstNeighbor is the first neighbor of node along the given types in direction -- the single-step lookup idiom (a message's creator, a person's city). ok is false when there is none. FirstNeighborMatch is FirstNeighbor over a pre-resolved RelMatch. FoldVia folds the m-matched rels (in dir) into a weighted node-pair map by projecting both endpoints of each rel through projection -- the one-mode / bipartite projection ("network folding") of a relation onto a derived node set. For every matched rel a -> b, a' = projection[a] and b' = projection[b] add one to the unordered pair count; self-pairs and endpoints projecting to NoNeighbor are skipped. projection is a flat node -> node array (a NeighborVia or RootsVia). Runs in parallel over the id space, per-chunk maps merged small-into-large. Follow walks a fixed chain of single-rel steps from start, taking the first neighbor at each step (e.g. person -> city -> country); ok is false as soon as a step has no neighbor. FullTextSearch returns the nodes of label whose key string property contains every token in query (boolean AND); empty for an unknown label/key, an empty query, or a token no document contains. The result composes with NodesWithLabel and other sets via And/Or/AndNot. FullTextSearchRanked returns the top k nodes of label by BM25 relevance of their key property to query (disjunctive), sorted by score descending, ties by ascending node id. FunctionalVia reports whether relType is functional in dir -- every node has at most one such rel, so its reachability structure is a forest of chains (RootsVia's precondition). Verified once and cached. GeoKNN returns the k nodes of label nearest (lat, lon), sorted by increasing distance, ties by node id. GeoWithinBBox returns the nodes of label whose coordinates fall in the lat/lon rectangle; minLon > maxLon crosses the antimeridian. GeoWithinRadius returns the nodes of label within km great-circle distance of (lat, lon), reading the latKey/lonKey f64 properties. The per-field index builds lazily and caches. HasLabel reports whether node carries label -- the label-membership test. HasNeighborWithProperty reports whether any typed neighbor of node in direction has property key equal to value (any of string, int, int32, int64, float64, bool, or Value). The comparison value resolves to a Value once, outside the neighbor scan. HasRel reports whether node has at least one neighbor along the given types in direction -- the existence predicate behind "has any X rel". LCC is the local clustering coefficient: for each node v with undirected neighbor set N(v) (each neighbor once, self excluded), 0 if |N(v)| <= 1, else the number of forward rels between members of N(v) over |N(v)|*(|N(v)|-1). Label resolves a label name to its atom; ok is false when unknown. LabelDense returns a plain word-bitmap over the label's members when one is already cached or the label covers at least an eighth of the id space, else nil. A dense label's membership probe is then one load and mask (words[id>>6]>>(id&63)&1) instead of a compressed-set container search -- the per-candidate label test in pattern matching. Built lazily once per label; the returned slice is shared and must not be mutated. The density floor gates only the BUILD: a bitmap forced by a probe-heavy caller (LabelDenseForced) serves every later compile. LabelDenseForced builds (or returns) the label's word bitmap ignoring the density floor -- for callers that have measured probe volume high enough to amortize the id-space-proportional bitmap (an adaptive representation choice on observed access volume, never on query identity). nil only for an unknown label. Labels lists the node labels present, sorted by name (schema introspection; mirrors db.labels()). Match resolves relationship-type names to a reusable filter: resolve once and pass to the *Match traversal methods in a hot loop to skip the per-call string lookups. Zero names match every type; unknown names are dropped (an unresolvable name has no rels), so all-unknown matches nothing. The zero- and one-name paths are allocation-free, so the string-typed traversal conveniences stay cheap in hot loops. NeighborCounts is the histogram of neighbor nodes reached from sources via the m-matched rels in dir (how many of the sources point to each neighbor). Counts into pooled generation-stamped dense scratch. NeighborGroups starts a grouped-neighbor reduction over each source's m-matched neighbors in dir. NeighborVia is the single neighbor each node reaches via the functional relType in dir (one hop -- e.g. a message's hasCreator); the depth-1 sibling of RootsVia. Node-indexed; a node with no such neighbor maps to NoNeighbor. Built fresh, not cached. Neighborhood is the set of nodes whose hop distance from seed lies in the closed range [loHops, hiHops] -- 1..2 is "one or two hops out" (excludes seed), 0..2 includes it, 2..2 is exactly two hops. Returned as a set so membership is O(1) and intersecting with another set is one bitmap op. Neighbors iterates the neighbors of node in direction, restricted to the given relationship types (zero types match all). Direction Both yields matching outgoing neighbors then matching incoming ones; duplicate rels yield duplicate neighbors, so counting composes. For per-rel type or property access during traversal use Rels. Both accessors are thin inlinable closure constructors over neighborsYield, so a direct `for range` over them is allocation-free (the closure and its captures stay on the stack). NeighborsInSet iterates the typed neighbors of node that are members of set -- a label's nodes, a search result, or any precomputed set. Duplicate rels are preserved, so it composes with counting. NeighborsMatch is Neighbors over a pre-resolved RelMatch, for hot loops. NodeCount is the number of nodes in the graph. NodeExists reports whether id is an actual node rather than a gap in a sparse id space. The CSR pads its arrays to max-id+1, so ids inside the space are not necessarily nodes; scans, result emission, and per-node kernels consult this to keep phantoms out of results. On a legacy deserialized graph with no existence record, every in-space id is presumed to exist (dense loaders make the two identical). 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. NodeWithLabelProperty finds a single label-carrying node whose property key equals value -- the label-scoped sibling of NodeWithProperty, for keys unique only within a label. Returns the smallest matching node id; reuses the cached (label, key) index NodesWithProperty builds. NodeWithProperty finds a single node by a property value across ALL labels (unlike the label-scoped NodesWithProperty) -- for unique keys such as a uri. Returns the smallest matching node id. The label-free (key, value) index is built lazily and cached under a reserved sentinel. NodesWithLabel is the set of nodes carrying label; ok is false for an unknown label. The returned set is shared -- callers must not mutate it (Clone first). NodesWithProperty is NodesWithValue with a convenience value (string, int, int32, int64, float64, bool, or Value). NodesWithValue is the set of label-carrying nodes whose property key equals v -- the typed core of NodesWithProperty. The index for (label, key) is built lazily on first access and cached. The returned set is shared -- callers must not mutate it (Clone first). ok is false when the label/key is unknown or no node carries that value. PageRank runs iterations of synchronous pull updates with the given damping: PR0(v) = 1/|V|, then PRi(v) = (1-d)/|V| + d*(sum over in- neighbors of PRi-1(u)/outdeg(u) + the uniformly redistributed rank of sinks). Prop reads node's property key, chaining into typed reads: g.Prop(n, "age").I64Or(0). The zero Prop means absent. PropagateBFS runs first-claim value propagation from seeds under opts. Results are sorted by node id ascending; a seed node itself is a result (depth 1, its seed value) even when it expands nowhere. PropertyKey resolves a property-key name to its atom; ok is false when the key was never interned. RelCol resolves a reader for the relationship property key, indexed by outgoing-CSR position (see RelRef.Pos); ok is false when absent. RelColIndexed is RelCol with O(1) sparse reads -- ideal for per-rel weight reads inside a search. RelCount is the number of relationships in the graph. RelCountByType lists every type present with its count, sorted by name -- schema coverage in one pass off the cached count store. 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. RelProp reads a relationship property by outgoing-CSR position (as carried by RelRef.Pos) -- the rel analogue of Prop. 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. 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. RelTypeCount is the total rels of relType (0 if absent). Part of the lazily built per-type count store; see AvgDegree. RelTypeStats returns the full statistics entry for relType; ok is false when the type is absent. RelTypes lists the relationship types present, sorted by name (mirrors db.relationshipTypes()). For cardinalities use RelTypeCount or RelCountByType. Rels iterates the relationships incident to node in direction, each carrying the CSR position for property reads (see RelRef), outgoing matches then incoming ones. Zero types match all. Like Neighbors, both accessors are thin inlinable closure constructors, so a direct `for range` over them is allocation-free. RelsMatch is Rels over a pre-resolved RelMatch, for hot loops. RelsWithType is the set of outgoing-CSR positions of rels with relType; ok is false for an unknown type. Shared -- callers must not mutate it. ResolveString resolves an atom id to its string; ok is false when out of range. RootVia is the terminal of node's functional relType chain in dir (a terminal node maps to itself) -- a convenience over RootsVia; in a hot loop index the array instead. RootsVia is the per-node forest-root array for the functional relType chain in dir: roots[node] is the node reached by following the single relType rel until one with no such rel (a terminal node maps to itself). Built once per (direction, type) with path compression, then cached -- call once and index the slice, rather than RootVia per node. Intended for a rel that is functional in dir; malformed data (multiple such rels, or a cycle) follows the first neighbor in CSR order and is broken by a depth cap, resolving deterministically. SSSP is single-source shortest paths over forward rels with additive weights from the weightKey rel property ("" = unit weights); unreachable nodes get +Inf. Unit weights make every distance the hop count, so that case runs the BFS -- a unit-weight Dijkstra pays a heap push and pop plus map probes per relationship to rediscover the ordering a BFS queue gives for free (the same dispatch the COST-constant path search takes). A weight key that resolves no column also means unit weights. ToGraphSection converts this snapshot to the plain on-disk data model. ValueFromString resolves a string property value to its interned Value; ok is false when the string was never interned (so no property equals it). Version is the snapshot's version string; ok is false when none was set. WCC labels each node with the smallest node id in its weakly-connected component, flooding undirected (Both) rels in ascending id sweep order. WCCVia is connected components over only the m-matched rels, flooding in dir (pass Both for the usual weakly-connected sense over a stored-directed rel set, e.g. a reply forest). Nodes with no matching rel are their own singleton component. WeightedShortestPath is the shortest-path cost from source to target via bidirectional Dijkstra: it searches from both ends and meets in the middle, exploring far fewer nodes than a one-directional search for a point-to-point query. ok is false when target is unreachable. The backward search follows the reverse of dir, so weight must be symmetric (the usual case for an undirected Both traversal). For distances to many targets, or the path itself, use Dijkstra. WriteNQuads serializes the snapshot as an N-Quads document (see the package-level vocabulary above). Output order is deterministic -- version, then nodes in ascending id order (labels sorted, property keys sorted, outgoing rels in CSR order, each followed by its sorted rel properties) -- so equal graphs serialize byte-identically. WriteNQuadsFile writes the snapshot as an N-Quads file, gzip-compressed when path ends in ".gz". Any other compression wraps WriteNQuads in a caller-provided writer. WriteRCPG serializes this snapshot to RCPG bytes including property columns (see rustychickpeas-format's FORMAT.md for the layout). WriteRCPGFile serializes to an RCPG file on disk. WriteRCPGWith serializes with optional sections per opts; TopologyOnlyWriteOptions produces a lean traversal-only file (no property columns converted or written). func FromGraphSection(section *rcpg.GraphSection) *Snapshot func ReadNQuads(data []byte) (*Snapshot, error) func ReadNQuadsFile(path string) (*Snapshot, error) func ReadRCPG(b []byte) (*Snapshot, error) func ReadRCPGFile(path string) (*Snapshot, error) func (*Builder).Finalize(indexProperties ...string) *Snapshot func (*Manager).Snapshot(version string) (*Snapshot, bool) func github.com/freeeve/gochickpeas/gql/internal/graph.Native.Snapshot() *Snapshot func github.com/freeeve/gochickpeas/gql/internal/graph.(*SnapshotGraph).Snapshot() *Snapshot func NewBuilderFromSnapshot(g *Snapshot) *Builder func ParNeighborFold[T](g *Snapshot, node NodeID, dir Direction, m RelMatch, identity func() T, fold func(acc T, neighbor NodeID) T, reduce func(a, b T) T) T func (*Manager).AddSnapshot(g *Snapshot) func (*Manager).AddSnapshotWithVersion(version string, g *Snapshot) func github.com/freeeve/gochickpeas/gql.DefaultCacheFor(g *Snapshot) *gql.PlanCache func github.com/freeeve/gochickpeas/gql.Explain(g *Snapshot, query string) (string, error) func github.com/freeeve/gochickpeas/gql.ExplainCanonical(g *Snapshot, query string) (string, error) func github.com/freeeve/gochickpeas/gql.Prepare(g *Snapshot, query string) (*gql.Prepared, error) func github.com/freeeve/gochickpeas/gql.Run(g *Snapshot, query string) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql.RunUncached(g *Snapshot, query string) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql.RunUncachedWithParams(g *Snapshot, query string, params map[string]value.Value) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql.RunWithParams(g *Snapshot, query string, params map[string]value.Value) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql.(*PlanCache).Run(g *Snapshot, query string) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql.(*PlanCache).RunWithParams(g *Snapshot, query string, params map[string]value.Value) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql.(*Prepared).Execute(g *Snapshot, params map[string]value.Value) (*gql.Rows, error) func github.com/freeeve/gochickpeas/gql/internal/compile.ConstValue(ctx *eval.Ctx, e ast.Expr, slots map[string]int, g *Snapshot) (value.Value, bool) func github.com/freeeve/gochickpeas/gql/internal/compile.New(ctx *eval.Ctx, e ast.Expr, slots map[string]int, g *Snapshot) *compile.Compiled func github.com/freeeve/gochickpeas/gql/internal/graph.New(g *Snapshot) *graph.SnapshotGraph
SourceSize pairs a source node with its largest-cohort size. Size uint32 Source NodeID func (*NeighborGroups).Sizes() []SourceSize func (*NeighborGroups).TopBySize(count int, tieKey string) []SourceSize
Step is one link of a Follow chain. Dir Direction RelType string func (*NeighborGroups).Project(steps ...Step) *NeighborGroups func (*Snapshot).Follow(start NodeID, steps ...Step) (NodeID, bool)
StrCol is a resolved string column reader exposing interned atom ids. ID returns the atom id at pos; ok is false when absent. Note atom 0 ("") in a dense column means missing -- Prop.Str folds that in; this raw reader does not. IDs is the dense atom-id slice; ok is false for a sparse column. func Col.Str() StrCol
TemporalUnit is a calendar/clock component of an epoch-millis (UTC) i64, for a temporal group dimension -- mirroring openCypher's .year/.month/... func (*Aggregation).TemporalComponent(column string, unit TemporalUnit) *Aggregation const UnitDay const UnitHour const UnitMinute const UnitMonth const UnitSecond const UnitYear
Value is a property value: the Go port of the Rust ValueId tagged union. It is comparable -- usable as a map key with == -- with the same equality semantics as the Rust derive: strings compare by atom id and floats by IEEE-754 bit pattern (so NaN == NaN when the payloads match, and 0.0 != -0.0). Bool returns the boolean value; ok is false for other kinds. F64 returns the float value; ok is false for other kinds. I64 returns the integer value; ok is false for other kinds. Kind reports the value's discriminant. StrID returns the interned-string atom id; ok is false for other kinds. func BoolValue(v bool) Value func F64Value(v float64) Value func I64Value(v int64) Value func StrValue(atom uint32) Value func (*Builder).Prop(node NodeID, key string) (Value, bool) func Column.Get(pos uint32) (Value, bool) func Prop.Value() (Value, bool) func (*Snapshot).ValueFromString(s string) (Value, bool) func (*Aggregation).FilterVia(projection []NodeID, column string, allowed ...Value) *Aggregation func (*Snapshot).NodesWithValue(label, key string, v Value) (*nodeset.Set, bool)
ValueKind discriminates a Value. func Value.Kind() ValueKind const KindBool const KindF64 const KindI64 const KindStr
WeightFn returns the non-negative cost of traversing a rel (Dijkstra's assumption). It receives the step's source node and the RelRef, so it can read a stored weight via RelProp(rel.Pos, ...) or compute a derived cost; +Inf prunes the rel. func (*Snapshot).Dijkstra(source NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).DijkstraTo(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths func (*Snapshot).WeightedShortestPath(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) (float64, bool)
Package-Level Functions (total 25)
BoolValue is a boolean value.
BuildFullTextField indexes already label-filtered (node, text) documents.
BuildGeoIndex builds from (node, latDeg, lonDeg) points; non-finite or out-of-range coordinates are skipped.
CoCount weights by the number of shared centers (co-occurrence events).
CoDistinct weights by the number of distinct values of the property key read off each shared center (e.g. distinct co-occurrence days); a center lacking the key contributes nothing.
F64Value is a float value, stored by bit pattern.
FromGraphSection builds a snapshot from the on-disk data model. The section's slices and bitmaps are taken over; the caller must not reuse them.
HaversineKM is the great-circle distance in kilometres between two lat/lon points -- a public utility independent of the index.
I64Value is an integer value.
MatchAll matches every relationship type.
MatchNone matches no relationship type.
MatchType matches a single pre-resolved type, allocation-free.
NewAtoms builds the table from an id-ordered string slice. When the slice contains duplicates, the smallest id wins reverse lookups.
NewBuilder returns a builder with capacity hints (0 = the 2^20 default); the builder auto-grows past them.
NewBuilderFromSnapshot thaws g back into a Builder whose Finalize reproduces g -- a no-edit thaw -> Finalize -> WriteRCPG round trip is byte-identical for any snapshot Finalize itself can produce. Atom ids are preserved exactly (the interner is seeded from g's atom table), so labels, rel types, property keys, and string values stay valid across the thaw. Two lossy corners are inherited from the snapshot representation itself: - Dense columns cannot distinguish "never set" from the zero value, so the thaw stages a pair for every position of a dense column (including atom-0 positions of a dense string column, mirroring the read layer, which reports those as present ""). Since tasks/041 Go only finalizes numeric/bool columns dense at full coverage, so this zero-fill materialization arises for those dtypes only when thawing a legacy or Rust-written file whose dense column was written at partial fill -- the missingness was destroyed at that write, and refinalize keeps the zero-filled positions as genuine (staged) values. - Ghost nodes -- isolated, unlabeled, propertyless -- leave no identifiable trace. Known nodes rebuild from labels, rel endpoints, and column positions; ghosts outside that union are lost (their count no longer contributes to NodeCount), and dense-column positions inside it may register ids the original builder never saw.
NewInterner returns an interner holding only atom 0 = "".
NewManager returns an empty registry.
Type Parameters: T: any ParNeighborFold folds node's typed neighbors in parallel, merging the per-chunk results -- NeighborsMatch composed with a parallel fold. Use when each neighbor drives substantial independent work; for light per-neighbor work iterate sequentially. The reduce runs in ascending chunk order, so the result is deterministic for any associative reduce.
ParseAggOp parses a comparison symbol (<, <=, >, >=, ==, !=).
ReadNQuads builds a Snapshot from an N-Quads or N-Triples document using the read mapping documented at the top of this file. Gzipped input (the 1f 8b magic) is decompressed transparently.
ReadNQuadsFile reads an N-Quads/N-Triples file (transparently gunzipping) into a Snapshot via ReadNQuads.
ReadRCPG reads a snapshot from RCPG bytes. Lazy indexes rebuild on first use.
ReadRCPGFile reads a snapshot from an RCPG file on disk.
StrValue is an interned-string value holding an atom id.
Tokenize splits text into lowercased alphanumeric runs -- the shared tokenizer of the build and query paths.
Package-Level Variables (total 4)
ErrBadValue reports a property value of an unsupported type.
ErrCapacity reports exceeding the u32 node/rel ceiling.
ErrRelNotFound reports a rel-property set on a (u, v, type) that was never added.
ErrSchema reports an aggregation over an unknown column/label, a mistyped column, or an unsupported option combination.
Package-Level Constants (total 26)
Both follows rels in either direction.
DtypeBool is a boolean column.
DtypeF64 is a float column.
DtypeI64 is an integer column.
DtypeStr is an interned-string column.
Incoming follows rels from destination to source.
KindBool is a boolean value.
KindF64 is a float value, stored by bit pattern.
KindI64 is an integer value.
KindStr is an interned-string value (the payload is an atom id).
LatestVersion is the registry key AddSnapshot uses for a snapshot that carries no version string.
NoMaxDepth removes the depth bound of a search.
NoNeighbor is the sentinel a NeighborVia array holds for a node with no such neighbor.
const OpEq AggOp = 4
const OpGe AggOp = 3
const OpGt AggOp = 2
const OpLe AggOp = 1
const OpLt AggOp = 0
const OpNe AggOp = 5
Outgoing follows rels from source to destination.