chickpeas

package module
v0.27.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 27 Imported by: 0

README

gochickpeas

A fast, in-memory graph database for Go: Roaring-bitmap adjacency, CSR traversal, columnar properties, a suite of graph-analytics kernels, and a read-only GQL query engine--with no external runtime dependencies.

gochickpeas is a Go port of RustyChickpeas and reads and writes the .rcpg graph format byte-for-byte compatibly with it, so graphs move between the two engines with no conversion step.

Go Reference

Features

  • Graph core: immutable, columnar snapshots built through a Builder; CSR adjacency with Roaring-bitmap label and relationship sets; lazily built equality, full-text, and geo indexes.
  • Traversal and search: the BFS family, Dijkstra, and bidirectional weighted shortest paths, exposed as Go iterators.
  • Analytics: the Graphalytics set--WCC, PageRank, CDLP, LCC, and SSSP.
  • Aggregation: composable co-occurrence, neighbor-grouping, and fold/roots primitives behind a fluent Aggregation API.
  • GQL query engine: a read-only engine speaking the ISO GQL read subset--pattern matching with quantified and ANY/ALL SHORTEST paths, OPTIONAL MATCH, aggregation, CALL {} subqueries, CALL procedures over the analytics/full-text/geo kernels, EXPLAIN/PROFILE, prepared statements, and a byte-budgeted plan cache.
  • Interchange: the RCPG graph-file codec (byte-compatible with RustyChickpeas) and RDF N-Quads/N-Triples import/export with transparent gzip.
  • Conformance-tested: the RCPG/RRSR codecs are checked byte-for-byte against the Rust implementation in both directions, and query results are pinned to a cross-checked golden corpus.

Install

go get github.com/freeeve/gochickpeas

Requires Go 1.25 or newer.

Quick start

Build and traverse a graph
b := chickpeas.NewBuilder(0, 0)
alice, _ := b.AddNode("Person")
bob, _ := b.AddNode("Person")
b.SetProp(alice, "name", "Alice")
b.AddRel(alice, bob, "KNOWS")
g := b.Finalize()

for n := range g.Neighbors(alice, chickpeas.Outgoing, "KNOWS") {
    fmt.Println(g.Prop(n, "name").StrOr("?"))
}
Query with GQL
rows, err := gql.Run(g,
    "MATCH (p:Person)-[:KNOWS]->(f:Person) WHERE p.age > 30 "+
        "RETURN f.name AS name, count(*) AS c ORDER BY c DESC LIMIT 10")
if err != nil {
    log.Fatal(err)
}
for row := range rows.All() {
    name, _ := row.Get("name")
    c, _ := row.Get("c")
    fmt.Println(name, c)
}

The supported query surface is documented in gql/GRAMMAR.md.

Read a graph file
raw, _ := os.ReadFile("graph.rcpg")
g, err := rcpg.Parse(raw) // or rcpg.ParseWith(raw, rcpg.TopologyOnlyParseOptions())
if err != nil {
    log.Fatal(err)
}
for _, nbr := range g.OutNeighbors(42) {
    // ...
}

Packages

  • chickpeas (root): the engine. NewBuilder(...) -> Finalize() -> *Snapshot queries; ReadRCPGFile/WriteRCPGFile for interchange, and ReadNQuads/WriteNQuads for RDF import/export (deterministic output, relationship properties via named-graph-per-edge, transparent gzip on read, .gz suffix on write).
  • gql: the read-only GQL query engine over a *Snapshot.
  • rcpg: the RCPG graph-file codec--Parse/Write, topology-only options, and lazy section-planned loading (ParseLazy/SectionFetch) for range-fetched transports.
  • rcpg/rrsr: the RRSR record store, with batched range planning over per-node payloads.
  • nodeset: the Roaring-backed node-id set that query results compose through.
  • flatset, parallel: flat probe sets/maps and chunked worker pools. Exported so the external LDBC benchmark harness can import them; implementation helpers, not a stable API surface.

Documentation

Development

go test ./... -race                          # unit + conformance tests
go test ./rcpg -fuzz=FuzzParse -fuzztime=30s # fuzz the codec

The golden conformance corpus in rcpg/testdata/conformance/ is generated by the Rust repo, which owns the frozen byte-layout specification, and the Go codec is tested against it in both directions.

License

MIT--see LICENSE.

Documentation

Overview

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.

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.

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.

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.

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.

Example (ManagerWriteLoop)

Example_managerWriteLoop demonstrates the read-modify-refinalize-swap write pattern: thaw the current snapshot into a builder, edit it (additions and removals alike), Finalize a new immutable snapshot, and register it in the Manager. Readers keep whatever snapshot they already hold -- the registry swap is the commit point, and no snapshot is ever mutated.

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("?"))
	}
}
Output:
v1: 2 nodes, 1 rels
v2: 2 nodes, 1 rels
alice now knows carol

Index

Examples

Constants

View Source
const LatestVersion = "latest"

LatestVersion is the registry key AddSnapshot uses for a snapshot that carries no version string.

View Source
const NoMaxDepth = -1

NoMaxDepth removes the depth bound of a search.

View Source
const NoNeighbor = NodeID(^uint32(0))

NoNeighbor is the sentinel a NeighborVia array holds for a node with no such neighbor.

Variables

View Source
var ErrBadValue = errors.New("unsupported property value type")

ErrBadValue reports a property value of an unsupported type.

View Source
var ErrCapacity = errors.New("capacity exceeded")

ErrCapacity reports exceeding the u32 node/rel ceiling.

View Source
var ErrRelNotFound = errors.New("relationship not found")

ErrRelNotFound reports a rel-property set on a (u, v, type) that was never added.

View Source
var ErrSchema = errors.New("schema error")

ErrSchema reports an aggregation over an unknown column/label, a mistyped column, or an unsupported option combination.

Functions

func HaversineKM

func HaversineKM(lat1, lon1, lat2, lon2 float64) float64

HaversineKM is the great-circle distance in kilometres between two lat/lon points -- a public utility independent of the index.

func ParNeighborFold

func ParNeighborFold[T any](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

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.

func Tokenize

func Tokenize(text string) []string

Tokenize splits text into lowercased alphanumeric runs -- the shared tokenizer of the build and query paths.

Types

type AggOp

type AggOp uint8

AggOp is a comparison operator for Aggregation filters.

const (
	OpLt AggOp = iota
	OpLe
	OpGt
	OpGe
	OpEq
	OpNe
)

func ParseAggOp

func ParseAggOp(s string) (AggOp, error)

ParseAggOp parses a comparison symbol (<, <=, >, >=, ==, !=).

func (AggOp) Test

func (op AggOp) Test(a, b int64) bool

Test applies the operator.

type AggResult

type AggResult struct {
	// Total counts rows passing the population (Filter) predicates.
	Total uint64
	// Rows holds one AggRow per group, unordered.
	Rows []AggRow
	// Fields names each key position: "label", a column name, or
	// "{col}_bin" / "{col}_{unit}" / "neighbor" / "endpoint".
	Fields []string
}

AggResult is the outcome of Run.

type AggRow

type AggRow struct {
	Key   []int64
	Count uint64
	Sum   *int64
}

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.

type Aggregation

type Aggregation struct {
	// contains filtered or unexported fields
}

Aggregation is a fluent parallel grouped reduction; build with Snapshot.Aggregate, chain the steps, then Run.

func (*Aggregation) Bin

func (a *Aggregation) Bin(column string, bounds ...int64) *Aggregation

Bin groups by a column bucketed at ascending bounds (bucket = count of bounds <= value; field = "{column}_bin").

func (*Aggregation) By

func (a *Aggregation) By(column string) *Aggregation

By groups by an i64 column's value (field = the column name).

func (*Aggregation) ByLabel

func (a *Aggregation) ByLabel() *Aggregation

ByLabel groups by the source node label (key = its index; field "label").

func (*Aggregation) ByLabelMembership

func (a *Aggregation) ByLabelMembership(label string) *Aggregation

ByLabelMembership groups by membership of one label (key 0/1; field = the label name) -- the n:Label predicate as a dimension, distinct from ByLabel.

func (*Aggregation) Filter

func (a *Aggregation) Filter(column string, op AggOp, value int64) *Aggregation

Filter adds the population predicate `column op value`; rows passing all filters are counted in Total.

func (*Aggregation) FilterVia

func (a *Aggregation) FilterVia(projection []NodeID, column string, allowed ...Value) *Aggregation

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.

func (*Aggregation) Having

func (a *Aggregation) Having(column string, op AggOp, value int64) *Aggregation

Having adds a predicate applied to grouped rows only (after the population filters).

func (*Aggregation) Hop

func (a *Aggregation) Hop(relType string, dir Direction) *Aggregation

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.

func (*Aggregation) OnlyNeighbors

func (a *Aggregation) OnlyNeighbors(ids ...NodeID) *Aggregation

OnlyNeighbors restricts Through counting to these neighbors.

func (*Aggregation) RequirePresent

func (a *Aggregation) RequirePresent(column string) *Aggregation

RequirePresent keeps only source nodes carrying a value for column (the IS NOT NULL predicate), regardless of dtype.

func (*Aggregation) Run

func (a *Aggregation) Run() (*AggResult, error)

Run executes the reduction in parallel and collects the groups.

func (*Aggregation) Sum

func (a *Aggregation) Sum(column string) *Aggregation

Sum also sums this i64 column per group.

func (*Aggregation) TemporalComponent

func (a *Aggregation) TemporalComponent(column string, unit TemporalUnit) *Aggregation

TemporalComponent groups by a temporal component of an epoch-millis column (field = "{column}_{unit}").

func (*Aggregation) Through

func (a *Aggregation) Through(relType string, dir Direction) *Aggregation

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.

type Atoms

type Atoms struct {
	// contains filtered or unexported fields
}

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).

func NewAtoms

func NewAtoms(strings []string) *Atoms

NewAtoms builds the table from an id-ordered string slice. When the slice contains duplicates, the smallest id wins reverse lookups.

func (*Atoms) ID

func (a *Atoms) ID(s string) (uint32, bool)

ID returns the atom id for a string; ok is false when never interned.

func (*Atoms) Len

func (a *Atoms) Len() int

Len is the number of atoms.

func (*Atoms) Resolve

func (a *Atoms) Resolve(id uint32) (string, bool)

Resolve returns the string for an atom id; ok is false when out of range.

func (*Atoms) Strings

func (a *Atoms) Strings() []string

Strings exposes the id-ordered table (for serialization). Callers must not mutate it.

type BoolCol

type BoolCol struct {
	// contains filtered or unexported fields
}

BoolCol is a resolved boolean column reader.

func (BoolCol) Bits

func (c BoolCol) Bits() (*bitset.Bits, bool)

Bits is the dense bit vector indexed directly by position; ok is false for a sparse column.

func (BoolCol) Get

func (c BoolCol) Get(pos uint32) (bool, bool)

Get returns the value at pos; ok is false when absent.

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder stages a graph for finalization.

func NewBuilder

func NewBuilder(capNodes, capRels int) *Builder

NewBuilder returns a builder with capacity hints (0 = the 2^20 default); the builder auto-grows past them.

func NewBuilderFromSnapshot added in v0.7.0

func NewBuilderFromSnapshot(g *Snapshot) *Builder

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.

func (*Builder) AddNode

func (b *Builder) AddNode(labels ...string) (NodeID, error)

AddNode adds a node with an auto-generated sequential id.

func (*Builder) AddNodeWithID

func (b *Builder) AddNodeWithID(id NodeID, labels ...string) (NodeID, error)

AddNodeWithID adds (or re-labels) the node with the given id; callers map their own identifiers onto the u32 space.

func (*Builder) AddRel

func (b *Builder) AddRel(u, v NodeID, relType string) (int, error)

AddRel adds a relationship from u to v, returning its rel index (usable with SetRelPropAt). Endpoints are registered as known nodes.

func (*Builder) Finalize

func (b *Builder) Finalize(indexProperties ...string) *Snapshot

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.

func (*Builder) InternPropertyKey

func (b *Builder) InternPropertyKey(name string) PropertyKey

InternPropertyKey interns a property-key name (or any string) and returns its atom, for reuse with SetPropByKey across many rows.

func (*Builder) NeighborIDs

func (b *Builder) NeighborIDs(node NodeID, dir Direction) []NodeID

NeighborIDs lists node's staged neighbors in direction (outgoing then incoming for Both), skipping removed rels -- an O(rels) pre-finalization scan.

func (*Builder) NodeCount

func (b *Builder) NodeCount() int

NodeCount is the number of distinct nodes staged so far.

func (*Builder) NodeLabels

func (b *Builder) NodeLabels(node NodeID) []string

NodeLabels lists node's staged labels in insertion order.

func (*Builder) NodesWithProperty

func (b *Builder) NodesWithProperty(label, key string, value any) []NodeID

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).

func (*Builder) Prop

func (b *Builder) Prop(node NodeID, key string) (Value, bool)

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.

func (*Builder) RelCount

func (b *Builder) RelCount() int

RelCount is the number of live relationships staged so far (tombstoned rels and pending detach-delete cascades excluded).

func (*Builder) RemoveNode added in v0.7.0

func (b *Builder) RemoveNode(id NodeID) bool

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.

func (*Builder) RemoveProp added in v0.7.0

func (b *Builder) RemoveProp(node NodeID, key string) bool

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)).

func (*Builder) RemoveRel added in v0.7.0

func (b *Builder) RemoveRel(relIdx int) error

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).

func (*Builder) RemoveRelProp added in v0.7.0

func (b *Builder) RemoveRelProp(u, v NodeID, relType, key string) (bool, error)

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.

func (*Builder) RemoveRelPropAt added in v0.7.0

func (b *Builder) RemoveRelPropAt(relIdx int, key string) (bool, error)

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.

func (*Builder) ResolveString

func (b *Builder) ResolveString(id uint32) (string, bool)

ResolveString resolves an interner atom back to its string (for reading staged Prop values); ok is false when out of range.

func (*Builder) SetProp

func (b *Builder) SetProp(node NodeID, key string, value any) error

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.

func (*Builder) SetPropByKey

func (b *Builder) SetPropByKey(node NodeID, key PropertyKey, value any) error

SetPropByKey is SetProp with a pre-interned key (see InternPropertyKey).

func (*Builder) SetRelProp

func (b *Builder) SetRelProp(u, v NodeID, relType, key string, value any) error

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.

func (*Builder) SetRelPropAt

func (b *Builder) SetRelPropAt(relIdx int, key string, value any) error

SetRelPropAt stages a property on the rel at the given index (as returned by AddRel).

func (*Builder) SetVersion

func (b *Builder) SetVersion(version string)

SetVersion sets the snapshot-level version string.

func (*Builder) UpdateProp

func (b *Builder) UpdateProp(node NodeID, key string, value any) error

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).

type CoWeight

type CoWeight struct {
	// contains filtered or unexported fields
}

CoWeight selects how CoOccurring accumulates each co-occurring node's weight (declarative -- the kernel needs no per-element callback).

func CoCount

func CoCount() CoWeight

CoCount weights by the number of shared centers (co-occurrence events).

func CoDistinct

func CoDistinct(key string) CoWeight

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.

type Col

type Col struct {
	// contains filtered or unexported fields
}

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).

func (Col) Bool

func (c Col) Bool() BoolCol

Bool narrows to a typed boolean reader.

func (Col) Column

func (c Col) Column() Column

Column is the raw generic reader.

func (Col) Dtype

func (c Col) Dtype() Dtype

Dtype is the column's logical element type, for picking a typed reader without narrowing.

func (Col) F64

func (c Col) F64() F64Col

F64 narrows to a typed float reader.

func (Col) I64

func (c Col) I64() I64Col

I64 narrows to a typed integer reader; a non-integer column reads back as absent, like a mistyped Prop.

func (Col) Str

func (c Col) Str() StrCol

Str narrows to a typed string reader exposing interned atom ids; resolve a comparison string to its atom once and compare ids.

type Column

type Column interface {
	// Get returns the value at pos; ok is false when absent.
	Get(pos uint32) (Value, bool)
	// Entries iterates (position, value) pairs in ascending position order.
	Entries() iter.Seq2[uint32, Value]
	// Dtype is the column's logical element type.
	Dtype() Dtype
	// Len is the number of positions carrying a value.
	Len() int
}

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.

type CommonNeighborCount

type CommonNeighborCount struct {
	Source, Target NodeID
	Count          uint64
}

CommonNeighborCount is one (source, target, count) triple of CommonNeighborCounts.

type Direction

type Direction uint8

Direction selects which adjacency a traversal follows.

const (
	// Outgoing follows rels from source to destination.
	Outgoing Direction = iota
	// Incoming follows rels from destination to source.
	Incoming
	// Both follows rels in either direction.
	Both
)

func (Direction) Reverse

func (d Direction) Reverse() Direction

Reverse flips Outgoing and Incoming; Both is its own reverse.

func (Direction) String

func (d Direction) String() string

String implements fmt.Stringer.

type Dtype

type Dtype uint8

Dtype is the logical element type of a column, reported without narrowing.

const (
	// DtypeI64 is an integer column.
	DtypeI64 Dtype = iota
	// DtypeF64 is a float column.
	DtypeF64
	// DtypeBool is a boolean column.
	DtypeBool
	// DtypeStr is an interned-string column.
	DtypeStr
)

type F64Col

type F64Col struct {
	// contains filtered or unexported fields
}

F64Col is a resolved float column reader.

func (F64Col) Get

func (c F64Col) Get(pos uint32) (float64, bool)

Get returns the value at pos; ok is false when absent.

func (F64Col) Slice

func (c F64Col) Slice() ([]float64, bool)

Slice is the dense value slice; ok is false for a sparse column.

func (F64Col) SliceRange added in v0.15.0

func (c F64Col) SliceRange() (start uint32, vals []float64, ok bool)

SliceRange is I64Col.SliceRange for float columns.

type FullTextField

type FullTextField struct {
	// contains filtered or unexported fields
}

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.

func BuildFullTextField

func BuildFullTextField(docs func(yield func(node uint32, text string) bool)) *FullTextField

BuildFullTextField indexes already label-filtered (node, text) documents.

func (*FullTextField) DocCount

func (f *FullTextField) DocCount() int

DocCount is the number of indexed documents (nodes with non-empty text).

func (*FullTextField) Query

func (f *FullTextField) Query(query string) *nodeset.Set

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.

func (*FullTextField) QueryRanked

func (f *FullTextField) QueryRanked(query string, k int) []RankedHit

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.

func (*FullTextField) TermCount

func (f *FullTextField) TermCount() int

TermCount is the number of distinct indexed tokens.

type GeoHit

type GeoHit struct {
	Node uint32
	KM   float64
}

GeoHit is one KNN result.

type GeoIndex

type GeoIndex struct {
	// contains filtered or unexported fields
}

GeoIndex is the immutable index for one (label, latKey, lonKey) field.

func BuildGeoIndex

func BuildGeoIndex(points func(yield func(node uint32, lat, lon float64) bool)) *GeoIndex

BuildGeoIndex builds from (node, latDeg, lonDeg) points; non-finite or out-of-range coordinates are skipped.

func (*GeoIndex) KNN

func (g *GeoIndex) KNN(lat, lon float64, k int) []GeoHit

KNN returns up to k nearest nodes to (lat, lon), sorted by increasing distance, ties by ascending node id.

func (*GeoIndex) Len

func (g *GeoIndex) Len() int

Len is the number of indexed points.

func (*GeoIndex) WithinBBox

func (g *GeoIndex) WithinBBox(minLat, minLon, maxLat, maxLon float64) *nodeset.Set

WithinBBox returns the nodes inside the lat/lon rectangle; minLon > maxLon treats the box as crossing the antimeridian.

func (*GeoIndex) WithinRadius

func (g *GeoIndex) WithinRadius(lat, lon, km float64) *nodeset.Set

WithinRadius returns the nodes within km great-circle distance of (lat, lon).

type I64Col

type I64Col struct {
	// contains filtered or unexported fields
}

I64Col is a resolved integer column reader.

func (I64Col) Get

func (c I64Col) Get(pos uint32) (int64, bool)

Get returns the value at pos (a node id for node columns, a CSR position for rel columns); ok is false when absent.

func (I64Col) GetMany added in v0.25.0

func (c I64Col) GetMany(ids []uint32, vals []int64, present []bool)

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.

func (I64Col) Slice

func (c I64Col) Slice() ([]int64, bool)

Slice is the dense value slice indexed directly by position; ok is false for a sparse column (fall back to Get).

func (I64Col) SliceRange added in v0.15.0

func (c I64Col) SliceRange() (start uint32, vals []int64, ok bool)

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.

type Interner

type Interner struct {
	// contains filtered or unexported fields
}

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.

func NewInterner

func NewInterner() *Interner

NewInterner returns an interner holding only atom 0 = "".

func (*Interner) Atoms

func (in *Interner) Atoms() *Atoms

Atoms snapshots the interner into an immutable table.

func (*Interner) Get

func (in *Interner) Get(s string) (uint32, bool)

Get returns s's atom id without interning; ok is false when unknown.

func (*Interner) GetOrIntern

func (in *Interner) GetOrIntern(s string) uint32

GetOrIntern returns s's atom id, interning it if new.

func (*Interner) Len

func (in *Interner) Len() int

Len is the number of interned strings (including atom 0).

func (*Interner) Resolve

func (in *Interner) Resolve(id uint32) (string, bool)

Resolve returns the string for an atom id; ok is false when out of range.

type Label

type Label uint32

Label is an interned node-label atom. Resolve text via the snapshot.

func (Label) ID

func (l Label) ID() uint32

ID is the raw atom id.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager holds named immutable snapshots.

func NewManager

func NewManager() *Manager

NewManager returns an empty registry.

func (*Manager) AddSnapshot

func (m *Manager) AddSnapshot(g *Snapshot)

AddSnapshot registers g under its own version string, or LatestVersion when it has none, replacing any previous snapshot under that key.

func (*Manager) AddSnapshotWithVersion

func (m *Manager) AddSnapshotWithVersion(version string, g *Snapshot)

AddSnapshotWithVersion registers g under an explicit version key.

func (*Manager) Clear

func (m *Manager) Clear()

Clear drops every registered snapshot.

func (*Manager) Len

func (m *Manager) Len() int

Len is the number of registered snapshots.

func (*Manager) RemoveSnapshot

func (m *Manager) RemoveSnapshot(version string) bool

RemoveSnapshot drops the snapshot under version, reporting whether one was present.

func (*Manager) Snapshot

func (m *Manager) Snapshot(version string) (*Snapshot, bool)

Snapshot returns the snapshot registered under version; ok is false when absent.

func (*Manager) Versions

func (m *Manager) Versions() []string

Versions lists the registered version keys (unordered).

type NeighborGroups

type NeighborGroups struct {
	// contains filtered or unexported fields
}

NeighborGroups is built by Snapshot.NeighborGroups; chain Project, then call a terminal.

func (*NeighborGroups) Project

func (n *NeighborGroups) Project(steps ...Step) *NeighborGroups

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).

func (*NeighborGroups) Sizes

func (n *NeighborGroups) Sizes() []SourceSize

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.

func (*NeighborGroups) TopBySize

func (n *NeighborGroups) TopBySize(count int, tieKey string) []SourceSize

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.

type NodeFilter

type NodeFilter func(node NodeID, g *Snapshot) bool

NodeFilter gates a node's participation in a search; nil means no filter.

type NodeID

type NodeID = uint32

NodeID identifies a node. u32 bounds the graph at ~4.3B nodes and keeps roaring bitmaps and CSR arrays compact.

type NodePair

type NodePair struct {
	Lo, Hi NodeID
}

NodePair is an unordered node pair (Lo <= Hi), the key of FoldVia.

type Prop

type Prop struct {
	// contains filtered or unexported fields
}

Prop is a property read result. The zero value reads as absent: every accessor returns not-ok / its default.

func (Prop) Bool

func (p Prop) Bool() (bool, bool)

Bool returns the boolean value; ok is false when absent or not a boolean.

func (Prop) BoolOr

func (p Prop) BoolOr(def bool) bool

BoolOr returns the boolean value, or def when absent or not a boolean.

func (Prop) F64

func (p Prop) F64() (float64, bool)

F64 returns the float value; ok is false when absent or not a float.

func (Prop) F64Or

func (p Prop) F64Or(def float64) float64

F64Or returns the float value, or def when absent or not a float.

func (Prop) I64

func (p Prop) I64() (int64, bool)

I64 returns the integer value; ok is false when absent or not an integer.

func (Prop) I64Or

func (p Prop) I64Or(def int64) int64

I64Or returns the integer value, or def when absent or not an integer.

func (Prop) Str

func (p Prop) Str() (string, bool)

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).

func (Prop) StrOr

func (p Prop) StrOr(def string) string

StrOr returns the string value, or def when absent / not a string / empty.

func (Prop) Value

func (p Prop) Value() (Value, bool)

Value returns the raw value; ok is false when the property is absent.

type PropagateOpts added in v0.8.0

type PropagateOpts struct {
	// RelTypes is the fan-out union of relationship types.
	RelTypes []string
	// Direction of expansion from each claimed node.
	Direction Direction
	// MaxDepth bounds the traversal: seeds sit at depth 1 and nodes expand
	// while their depth is below MaxDepth (values below 1 mean seeds only).
	MaxDepth uint32
	// ValueProp is the float rel property a claiming rel carries to the
	// node it claims (absent values read as 0).
	ValueProp string
	// Desc orders each expansion's eligible rels by ValueProp descending
	// instead of ascending. Ties keep adjacency order (stable).
	Desc bool
	// TruncLimit caps each expansion's ordered rels (0 = no cap).
	TruncLimit int
	// MinValue is an exclusive lower bound on a claiming rel's carried
	// value; the default 0 propagates only positive values. Pass -Inf to
	// disable.
	MinValue float64
	// 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.
	FilterProp           string
	FilterMin, FilterMax int64
}

PropagateOpts parameterizes PropagateBFS. The zero value is not useful: set RelTypes (empty matches no rels), Direction, MaxDepth, and ValueProp.

type PropagateResult added in v0.8.0

type PropagateResult struct {
	Node  NodeID
	Value float64
	Depth uint32
}

PropagateResult is one reached node with its accumulated value and minimum depth (seeds are depth 1).

type PropagateSeed added in v0.8.0

type PropagateSeed struct {
	Node  NodeID
	Value float64
}

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).

type PropertyKey

type PropertyKey = uint32

PropertyKey is an interned property-key atom.

type RangeIndex added in v0.17.0

type RangeIndex struct {
	// contains filtered or unexported fields
}

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.

func (RangeIndex) Len added in v0.17.0

func (r RangeIndex) Len() int

Len is the number of indexed entries (nodes carrying the key).

func (RangeIndex) Window added in v0.17.0

func (r RangeIndex) Window(lo, hi int64, loIncl, hiIncl bool) []uint32

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.

type RankedHit

type RankedHit struct {
	Node  uint32
	Score float32
}

RankedHit is one QueryRanked result.

type RelFilter

type RelFilter func(from, to NodeID, t RelType, pos uint32, g *Snapshot) bool

RelFilter gates following a rel, receiving its stored (source, target) endpoints, type, and CSR position; nil means no filter.

type RelMatch

type RelMatch struct {
	// contains filtered or unexported fields
}

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

func MatchAll() RelMatch

MatchAll matches every relationship type.

func MatchNone

func MatchNone() RelMatch

MatchNone matches no relationship type.

func MatchType

func MatchType(t RelType) RelMatch

MatchType matches a single pre-resolved type, allocation-free.

type RelRef

type RelRef struct {
	Neighbor  NodeID
	Type      RelType
	Direction Direction
	Pos       uint32
}

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).

type RelStats

type RelStats struct {
	// Count is the total rels of this type.
	Count uint64
	// OutSources is the distinct nodes that are the source of such a rel.
	OutSources uint64
	// InSources is the distinct nodes that are the target of such a rel
	// (the source when traversed incoming).
	InSources uint64
}

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.

type RelType

type RelType uint32

RelType is an interned relationship-type atom. Resolve text via the snapshot.

func (RelType) ID

func (t RelType) ID() uint32

ID is the raw atom id.

type RelTypeCountEntry

type RelTypeCountEntry struct {
	Type  string
	Count uint64
}

RelTypeCountEntry pairs a relationship type name with its total count.

type RootsVia

type RootsVia []NodeID

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.

type ShortestPaths

type ShortestPaths struct {
	// contains filtered or unexported fields
}

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.

func (*ShortestPaths) Distance

func (p *ShortestPaths) Distance(node NodeID) (float64, bool)

Distance is the shortest distance from the source to node; ok is false when unreached.

func (*ShortestPaths) Distances

func (p *ShortestPaths) Distances() map[NodeID]float64

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.

func (*ShortestPaths) PathTo

func (p *ShortestPaths) PathTo(target NodeID) ([]NodeID, bool)

PathTo is the shortest path from the source to target as a node sequence (source first); ok is false when target was unreached.

func (*ShortestPaths) Reached

func (p *ShortestPaths) Reached(node NodeID) bool

Reached reports whether node was reached from the source.

type Snapshot

type Snapshot struct {
	// contains filtered or unexported fields
}

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.

func FromGraphSection

func FromGraphSection(section *rcpg.GraphSection) *Snapshot

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.

func ReadNQuads added in v0.6.0

func ReadNQuads(data []byte) (*Snapshot, error)

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.

func ReadNQuadsFile added in v0.6.0

func ReadNQuadsFile(path string) (*Snapshot, error)

ReadNQuadsFile reads an N-Quads/N-Triples file (transparently gunzipping) into a Snapshot via ReadNQuads.

func ReadRCPG

func ReadRCPG(b []byte) (*Snapshot, error)

ReadRCPG reads a snapshot from RCPG bytes. Lazy indexes rebuild on first use.

func ReadRCPGFile

func ReadRCPGFile(path string) (*Snapshot, error)

ReadRCPGFile reads a snapshot from an RCPG file on disk.

func (*Snapshot) Aggregate

func (g *Snapshot) Aggregate(labels ...string) *Aggregation

Aggregate starts a parallel grouped reduction over the given labels.

func (*Snapshot) AppendNeighborsEach added in v0.13.0

func (g *Snapshot) AppendNeighborsEach(dst []NodeID, node NodeID, dir Direction, m RelMatch) []NodeID

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.

func (*Snapshot) AppendNeighborsMatch added in v0.7.1

func (g *Snapshot) AppendNeighborsMatch(dst []NodeID, node NodeID, dir Direction, m RelMatch) []NodeID

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.

func (*Snapshot) AppendRelsBetweenMatch added in v0.20.0

func (g *Snapshot) AppendRelsBetweenMatch(dst []uint32, u, v NodeID, dir Direction, m RelMatch) []uint32

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.

func (*Snapshot) Atoms

func (g *Snapshot) Atoms() *Atoms

Atoms is the snapshot's interned-string table (atom <-> string in both directions).

func (*Snapshot) AvgDegree

func (g *Snapshot) AvgDegree(relType string, dir Direction) float64

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.

func (*Snapshot) AvgDegreeByLabel added in v0.21.0

func (g *Snapshot) AvgDegreeByLabel(label, relType string, dir Direction) (float64, bool)

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.

func (*Snapshot) BFS

func (g *Snapshot) BFS(start *nodeset.Set, dir Direction, m RelMatch,
	nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set)

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).

func (*Snapshot) BFSDistances

func (g *Snapshot) BFSDistances(start NodeID, dir Direction, m RelMatch, maxDepth int) map[NodeID]uint32

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.

func (*Snapshot) BidirectionalBFS

func (g *Snapshot) BidirectionalBFS(source, target *nodeset.Set, dir Direction, m RelMatch,
	nodeFilter NodeFilter, relFilter RelFilter, maxDepth int) (nodes, rels *nodeset.Set)

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.

func (*Snapshot) CDLP

func (g *Snapshot) CDLP(directed bool, iterations int) []uint32

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.

func (*Snapshot) CDLPSeeded

func (g *Snapshot) CDLPSeeded(directed bool, iterations int, init []uint32) []uint32

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.

func (*Snapshot) CSRIDSpace

func (g *Snapshot) CSRIDSpace() uint32

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.

func (*Snapshot) CanReach

func (g *Snapshot) CanReach(from, to NodeID, dir Direction, m RelMatch, maxDepth int) bool

CanReach reports whether to is reachable from from over the m-matched rels in dir, within maxDepth hops (NoMaxDepth = unbounded).

func (*Snapshot) ChainCollapseVia added in v0.14.0

func (g *Snapshot) ChainCollapseVia(relType string, dir Direction, label string) (RootsVia, bool)

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).

func (*Snapshot) CoOccurring

func (g *Snapshot) CoOccurring(seed NodeID, m RelMatch, dir Direction, w CoWeight) map[NodeID]uint64

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.

func (*Snapshot) Col

func (g *Snapshot) Col(key string) (Col, bool)

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) ColIndexed

func (g *Snapshot) ColIndexed(key string) (Col, bool)

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) ColRangeIndex added in v0.17.0

func (g *Snapshot) ColRangeIndex(key string) (RangeIndex, bool)

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.

func (*Snapshot) CommonNeighborCounts

func (g *Snapshot) CommonNeighborCounts(sources []NodeID, dir Direction, m RelMatch, targets *nodeset.Set) []CommonNeighborCount

func (*Snapshot) CommonNeighbors

func (g *Snapshot) CommonNeighbors(a, b NodeID, dir Direction, m RelMatch) *nodeset.Set

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.

func (*Snapshot) CountNeighborsMatch added in v0.11.0

func (g *Snapshot) CountNeighborsMatch(u, v NodeID, dir Direction, m RelMatch) int

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.

func (*Snapshot) Degree added in v0.8.0

func (g *Snapshot) Degree(node NodeID, dir Direction) int

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.

func (*Snapshot) Dijkstra

func (g *Snapshot) Dijkstra(source NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths

Dijkstra runs weighted single-source shortest paths from source over the m-matched rels in dir, reaching the whole component.

func (*Snapshot) DijkstraTo

func (g *Snapshot) DijkstraTo(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) *ShortestPaths

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.

func (*Snapshot) DroppedCrossTypedStagings added in v0.26.0

func (g *Snapshot) DroppedCrossTypedStagings() int

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.

func (*Snapshot) FirstNeighbor

func (g *Snapshot) FirstNeighbor(node NodeID, dir Direction, relTypes ...string) (NodeID, bool)

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.

func (*Snapshot) FirstNeighborMatch

func (g *Snapshot) FirstNeighborMatch(node NodeID, dir Direction, m RelMatch) (NodeID, bool)

FirstNeighborMatch is FirstNeighbor over a pre-resolved RelMatch.

func (*Snapshot) FoldVia

func (g *Snapshot) FoldVia(m RelMatch, dir Direction, projection []NodeID) map[NodePair]uint64

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.

func (*Snapshot) Follow

func (g *Snapshot) Follow(start NodeID, steps ...Step) (NodeID, bool)

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.

func (*Snapshot) FullTextSearch

func (g *Snapshot) FullTextSearch(label, key, query string) *nodeset.Set

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.

func (*Snapshot) FullTextSearchRanked

func (g *Snapshot) FullTextSearchRanked(label, key, query string, k int) []RankedHit

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.

func (*Snapshot) FunctionalVia added in v0.14.0

func (g *Snapshot) FunctionalVia(relType string, dir Direction) bool

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.

func (*Snapshot) GeoKNN

func (g *Snapshot) GeoKNN(label, latKey, lonKey string, lat, lon float64, k int) []GeoHit

GeoKNN returns the k nodes of label nearest (lat, lon), sorted by increasing distance, ties by node id.

func (*Snapshot) GeoWithinBBox

func (g *Snapshot) GeoWithinBBox(label, latKey, lonKey string, minLat, minLon, maxLat, maxLon float64) *nodeset.Set

GeoWithinBBox returns the nodes of label whose coordinates fall in the lat/lon rectangle; minLon > maxLon crosses the antimeridian.

func (*Snapshot) GeoWithinRadius

func (g *Snapshot) GeoWithinRadius(label, latKey, lonKey string, lat, lon, km float64) *nodeset.Set

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.

func (*Snapshot) HasLabel

func (g *Snapshot) HasLabel(node NodeID, label string) bool

HasLabel reports whether node carries label -- the label-membership test.

func (*Snapshot) HasNeighborWithProperty

func (g *Snapshot) HasNeighborWithProperty(node NodeID, dir Direction, key string, value any, relTypes ...string) bool

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.

func (*Snapshot) HasRel

func (g *Snapshot) HasRel(node NodeID, dir Direction, relTypes ...string) bool

HasRel reports whether node has at least one neighbor along the given types in direction -- the existence predicate behind "has any X rel".

func (*Snapshot) LCC

func (g *Snapshot) LCC(directed bool) []float64

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).

func (*Snapshot) Label

func (g *Snapshot) Label(name string) (Label, bool)

Label resolves a label name to its atom; ok is false when unknown.

func (*Snapshot) LabelDense added in v0.12.0

func (g *Snapshot) LabelDense(label string) []uint64

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.

func (*Snapshot) LabelDenseForced added in v0.14.7

func (g *Snapshot) LabelDenseForced(label string) []uint64

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.

func (*Snapshot) Labels

func (g *Snapshot) Labels() []string

Labels lists the node labels present, sorted by name (schema introspection; mirrors db.labels()).

func (*Snapshot) Match

func (g *Snapshot) Match(relTypes ...string) RelMatch

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.

func (*Snapshot) NeighborCounts

func (g *Snapshot) NeighborCounts(sources []NodeID, dir Direction, m RelMatch) map[NodeID]int

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.

func (*Snapshot) NeighborGroups

func (g *Snapshot) NeighborGroups(sources []NodeID, m RelMatch, dir Direction) *NeighborGroups

NeighborGroups starts a grouped-neighbor reduction over each source's m-matched neighbors in dir.

func (*Snapshot) NeighborVia

func (g *Snapshot) NeighborVia(t RelType, dir Direction) RootsVia

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.

func (*Snapshot) Neighborhood

func (g *Snapshot) Neighborhood(seed NodeID, dir Direction, m RelMatch, loHops, hiHops uint32) *nodeset.Set

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.

func (*Snapshot) Neighbors

func (g *Snapshot) Neighbors(node NodeID, dir Direction, relTypes ...string) iter.Seq[NodeID]

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).

func (*Snapshot) NeighborsInSet

func (g *Snapshot) NeighborsInSet(node NodeID, dir Direction, set *nodeset.Set, relTypes ...string) iter.Seq[NodeID]

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.

func (*Snapshot) NeighborsMatch

func (g *Snapshot) NeighborsMatch(node NodeID, dir Direction, m RelMatch) iter.Seq[NodeID]

NeighborsMatch is Neighbors over a pre-resolved RelMatch, for hot loops.

func (*Snapshot) NodeCount

func (g *Snapshot) NodeCount() uint32

NodeCount is the number of nodes in the graph.

func (*Snapshot) NodeExists added in v0.27.0

func (g *Snapshot) NodeExists(id NodeID) bool

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).

func (*Snapshot) NodePropertyKeys

func (g *Snapshot) NodePropertyKeys(node NodeID) []string

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) NodeWithLabelProperty

func (g *Snapshot) NodeWithLabelProperty(label, key string, value any) (NodeID, bool)

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.

func (*Snapshot) NodeWithProperty

func (g *Snapshot) NodeWithProperty(key string, value any) (NodeID, bool)

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.

func (*Snapshot) NodesWithLabel

func (g *Snapshot) NodesWithLabel(label string) (*nodeset.Set, bool)

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).

func (*Snapshot) NodesWithProperty

func (g *Snapshot) NodesWithProperty(label, key string, value any) (*nodeset.Set, bool)

NodesWithProperty is NodesWithValue with a convenience value (string, int, int32, int64, float64, bool, or Value).

func (*Snapshot) NodesWithValue

func (g *Snapshot) NodesWithValue(label, key string, v Value) (*nodeset.Set, bool)

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.

func (*Snapshot) PageRank

func (g *Snapshot) PageRank(directed bool, damping float64, iterations int) []float64

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).

func (*Snapshot) Prop

func (g *Snapshot) Prop(node NodeID, key string) Prop

Prop reads node's property key, chaining into typed reads: g.Prop(n, "age").I64Or(0). The zero Prop means absent.

func (*Snapshot) PropagateBFS added in v0.8.0

func (g *Snapshot) PropagateBFS(seeds []PropagateSeed, opts PropagateOpts) []PropagateResult

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.

func (*Snapshot) PropertyKey

func (g *Snapshot) PropertyKey(key string) (PropertyKey, bool)

PropertyKey resolves a property-key name to its atom; ok is false when the key was never interned.

func (*Snapshot) RelCol

func (g *Snapshot) RelCol(key string) (Col, bool)

RelCol resolves a reader for the relationship property key, indexed by outgoing-CSR position (see RelRef.Pos); ok is false when absent.

func (*Snapshot) RelColIndexed

func (g *Snapshot) RelColIndexed(key string) (Col, bool)

RelColIndexed is RelCol with O(1) sparse reads -- ideal for per-rel weight reads inside a search.

func (*Snapshot) RelCount

func (g *Snapshot) RelCount() uint64

RelCount is the number of relationships in the graph.

func (*Snapshot) RelCountByType

func (g *Snapshot) RelCountByType() []RelTypeCountEntry

RelCountByType lists every type present with its count, sorted by name -- schema coverage in one pass off the cached count store.

func (*Snapshot) RelEndpoints

func (g *Snapshot) RelEndpoints(pos uint32) (source, target NodeID, ok bool)

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) RelProp

func (g *Snapshot) RelProp(pos uint32, key string) Prop

RelProp reads a relationship property by outgoing-CSR position (as carried by RelRef.Pos) -- the rel analogue of Prop.

func (*Snapshot) RelType

func (g *Snapshot) RelType(name string) (RelType, bool)

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) RelTypeAt added in v0.18.0

func (g *Snapshot) RelTypeAt(pos uint32) (string, bool)

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) RelTypeCount

func (g *Snapshot) RelTypeCount(relType string) uint64

RelTypeCount is the total rels of relType (0 if absent). Part of the lazily built per-type count store; see AvgDegree.

func (*Snapshot) RelTypeStats

func (g *Snapshot) RelTypeStats(relType string) (RelStats, bool)

RelTypeStats returns the full statistics entry for relType; ok is false when the type is absent.

func (*Snapshot) RelTypes

func (g *Snapshot) RelTypes() []string

RelTypes lists the relationship types present, sorted by name (mirrors db.relationshipTypes()). For cardinalities use RelTypeCount or RelCountByType.

func (*Snapshot) Rels

func (g *Snapshot) Rels(node NodeID, dir Direction, relTypes ...string) iter.Seq[RelRef]

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.

func (*Snapshot) RelsMatch

func (g *Snapshot) RelsMatch(node NodeID, dir Direction, m RelMatch) iter.Seq[RelRef]

RelsMatch is Rels over a pre-resolved RelMatch, for hot loops.

func (*Snapshot) RelsWithType

func (g *Snapshot) RelsWithType(relType string) (*nodeset.Set, bool)

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.

func (*Snapshot) ResolveString

func (g *Snapshot) ResolveString(id uint32) (string, bool)

ResolveString resolves an atom id to its string; ok is false when out of range.

func (*Snapshot) RootVia

func (g *Snapshot) RootVia(node NodeID, t RelType, dir Direction) NodeID

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.

func (*Snapshot) RootsVia

func (g *Snapshot) RootsVia(t RelType, dir Direction) RootsVia

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.

func (*Snapshot) SSSP

func (g *Snapshot) SSSP(source NodeID, directed bool, weightKey string) []float64

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.

func (*Snapshot) ToGraphSection

func (g *Snapshot) ToGraphSection() *rcpg.GraphSection

ToGraphSection converts this snapshot to the plain on-disk data model.

func (*Snapshot) ValueFromString

func (g *Snapshot) ValueFromString(s string) (Value, bool)

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) Version

func (g *Snapshot) Version() (string, bool)

Version is the snapshot's version string; ok is false when none was set.

func (*Snapshot) WCC

func (g *Snapshot) WCC() []uint32

WCC labels each node with the smallest node id in its weakly-connected component, flooding undirected (Both) rels in ascending id sweep order.

func (*Snapshot) WCCVia

func (g *Snapshot) WCCVia(m RelMatch, dir Direction) []uint32

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.

func (*Snapshot) WeightedShortestPath

func (g *Snapshot) WeightedShortestPath(source, target NodeID, dir Direction, m RelMatch, weight WeightFn) (float64, bool)

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.

func (*Snapshot) WriteNQuads added in v0.6.0

func (g *Snapshot) WriteNQuads(w io.Writer) error

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.

func (*Snapshot) WriteNQuadsFile added in v0.6.0

func (g *Snapshot) WriteNQuadsFile(path string) error

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.

func (*Snapshot) WriteRCPG

func (g *Snapshot) WriteRCPG(w io.Writer) error

WriteRCPG serializes this snapshot to RCPG bytes including property columns (see rustychickpeas-format's FORMAT.md for the layout).

func (*Snapshot) WriteRCPGFile

func (g *Snapshot) WriteRCPGFile(path string) error

WriteRCPGFile serializes to an RCPG file on disk.

func (*Snapshot) WriteRCPGWith

func (g *Snapshot) WriteRCPGWith(w io.Writer, opts rcpg.WriteOptions) error

WriteRCPGWith serializes with optional sections per opts; TopologyOnlyWriteOptions produces a lean traversal-only file (no property columns converted or written).

type SourceSize

type SourceSize struct {
	Source NodeID
	Size   uint32
}

SourceSize pairs a source node with its largest-cohort size.

type Step

type Step struct {
	Dir     Direction
	RelType string
}

Step is one link of a Follow chain.

type StrCol

type StrCol struct {
	// contains filtered or unexported fields
}

StrCol is a resolved string column reader exposing interned atom ids.

func (StrCol) ID

func (c StrCol) ID(pos uint32) (uint32, bool)

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.

func (StrCol) IDs

func (c StrCol) IDs() ([]uint32, bool)

IDs is the dense atom-id slice; ok is false for a sparse column.

type TemporalUnit

type TemporalUnit uint8

TemporalUnit is a calendar/clock component of an epoch-millis (UTC) i64, for a temporal group dimension -- mirroring openCypher's .year/.month/...

const (
	UnitYear TemporalUnit = iota
	UnitMonth
	UnitDay
	UnitHour
	UnitMinute
	UnitSecond
)

type Value

type Value struct {
	// contains filtered or unexported fields
}

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).

func BoolValue

func BoolValue(v bool) Value

BoolValue is a boolean value.

func F64Value

func F64Value(v float64) Value

F64Value is a float value, stored by bit pattern.

func I64Value

func I64Value(v int64) Value

I64Value is an integer value.

func StrValue

func StrValue(atom uint32) Value

StrValue is an interned-string value holding an atom id.

func (Value) Bool

func (v Value) Bool() (bool, bool)

Bool returns the boolean value; ok is false for other kinds.

func (Value) F64

func (v Value) F64() (float64, bool)

F64 returns the float value; ok is false for other kinds.

func (Value) I64

func (v Value) I64() (int64, bool)

I64 returns the integer value; ok is false for other kinds.

func (Value) Kind

func (v Value) Kind() ValueKind

Kind reports the value's discriminant.

func (Value) StrID

func (v Value) StrID() (uint32, bool)

StrID returns the interned-string atom id; ok is false for other kinds.

type ValueKind

type ValueKind uint8

ValueKind discriminates a Value.

const (
	// KindStr is an interned-string value (the payload is an atom id).
	KindStr ValueKind = iota
	// KindI64 is an integer value.
	KindI64
	// KindF64 is a float value, stored by bit pattern.
	KindF64
	// KindBool is a boolean value.
	KindBool
)

type WeightFn

type WeightFn func(from NodeID, rel RelRef) float64

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.

Directories

Path Synopsis
cmd
gabench command
gabench runs the LDBC Graphalytics algorithms (BFS, PR, WCC, CDLP, LCC, SSSP) over .v/.e datasets and emits warm timings in the rustychickpeas-ldbc suite's JSONL schema as engine "gochickpeas (go)", Family "GA" -- next to rcp-native (rust).
gabench runs the LDBC Graphalytics algorithms (BFS, PR, WCC, CDLP, LCC, SSSP) over .v/.e datasets and emits warm timings in the rustychickpeas-ldbc suite's JSONL schema as engine "gochickpeas (go)", Family "GA" -- next to rcp-native (rust).
gqlbench command
Plan-shape golden: a diff-friendly plain-text snapshot of every manifest query's canonical EXPLAIN plan.
Plan-shape golden: a diff-friendly plain-text snapshot of every manifest query's canonical EXPLAIN plan.
ldbcnativebench command
ldbcnativebench runs the native parity manifest (native_variants.tsv, rustychickpeas-ldbc task 263 / gochickpeas task 025) against the per-query native Go kernels: each row's kernel runs on the row's graph, result rows are normalized and hashed per rowhash/v1, and only a hash-equal (MATCH) run may emit a timing -- as engine "gochickpeas (go)" in the suite's JSONL schema, joining the BI/IC/FinBench families next to rcp-native (rust).
ldbcnativebench runs the native parity manifest (native_variants.tsv, rustychickpeas-ldbc task 263 / gochickpeas task 025) against the per-query native Go kernels: each row's kernel runs on the row's graph, result rows are normalized and hashed per rowhash/v1, and only a hash-equal (MATCH) run may emit a timing -- as engine "gochickpeas (go)" in the suite's JSONL schema, joining the BI/IC/FinBench families next to rcp-native (rust).
loadbench command
loadbench times graph loads and appends family=LOAD records to the suite's JSONL, mirroring the rcp-native (rust) load emissions: query is the workload key (BI/FINBENCH/SPB), variant the on-disk format (rcpg, or nt for the SPB RDF path), rows = nodes + rels, and meta carries format/bytes/mb_s/rec_s.
loadbench times graph loads and appends family=LOAD records to the suite's JSONL, mirroring the rcp-native (rust) load emissions: query is the workload key (BI/FINBENCH/SPB), variant the on-disk format (rcpg, or nt for the SPB RDF path), rows = nodes + rels, and meta carries format/bytes/mb_s/rec_s.
nativemanifest command
nativemanifest generates the interim native parity manifest (native_variants.tsv) for cmd/ldbcnativebench by hashing the rustychickpeas-ldbc committed reference rows (python/refs) with rowhash/v1 -- the same refs and hash the GQL manifest carries, so a native kernel and its GQL twin gate against the identical oracle.
nativemanifest generates the interim native parity manifest (native_variants.tsv) for cmd/ldbcnativebench by hashing the rustychickpeas-ldbc committed reference rows (python/refs) with rowhash/v1 -- the same refs and hash the GQL manifest carries, so a native kernel and its GQL twin gate against the identical oracle.
rssbench command
rssbench measures the resident memory footprint of a loaded graph (task 213).
rssbench measures the resident memory footprint of a loaded graph (task 213).
spbexport command
spbexport builds the SPB property graph from the LDBC SPB N-Triples extract and writes it as a canonical .rcpg for the native kernels (task 026).
spbexport builds the SPB property graph from the LDBC SPB N-Triples extract and writes it as a canonical .rcpg for the native kernels (task 026).
weightedexport command
weightedexport materializes the BI weighted-shortest-path relations (q15weight, interactsWith, cohort, ic14weight -- each Person->Person with a float `w` property, both directions per undirected knows pair) onto a canonical LDBC rcpg, writing a sibling weighted rcpg the GQL manifest can point BI Q15/Q19/Q20 (and later IC14) at.
weightedexport materializes the BI weighted-shortest-path relations (q15weight, interactsWith, cohort, ic14weight -- each Person->Person with a float `w` property, both directions per undirected knows pair) onto a canonical LDBC rcpg, writing a sibling weighted rcpg the GQL manifest can point BI Q15/Q19/Q20 (and later IC14) at.
Package flatset provides flat open-addressing sets and maps for the dedup/membership/grouping structures that dominate allocation-heavy inner loops.
Package flatset provides flat open-addressing sets and maps for the dedup/membership/grouping structures that dominate allocation-heavy inner loops.
gql
PlanCache: a size-bounded LRU cache of auto-parameterized query plans.
PlanCache: a size-bounded LRU cache of auto-parameterized query plans.
internal/ast
Package ast is the language-neutral query AST: produced by the GQL parser (gql/internal/parser), consumed by desugar/bind/plan.
Package ast is the language-neutral query AST: produced by the GQL parser (gql/internal/parser), consumed by desugar/bind/plan.
internal/ast/asttest
Package asttest is shared test scaffolding for the exhaustive expression walkers (substitution, alpha-rename, reference checking): one buildable instance of every ast.Expr kind referencing a chosen free variable, plus a roll call that fails when the ast package grows a kind no walker test has decided a policy for.
Package asttest is shared test scaffolding for the exhaustive expression walkers (substitution, alpha-rename, reference checking): one buildable instance of every ast.Expr kind referencing a chosen free variable, plus a roll call that fails when the ast package grows a kind no walker test has decided a policy for.
internal/compile
Per-candidate predicate specialization: during one bind-chain level's candidate iteration every row slot except the level's own is fixed, so a pushed-down conjunct is a unary function of the candidate id.
Per-candidate predicate specialization: during one bind-chain level's candidate iteration every row slot except the level's own is fixed, so a pushed-down conjunct is a unary function of the candidate id.
internal/eval
Binary operator evaluation shared by the interpreter and the compiled path: string predicates (STARTS WITH / ENDS WITH / CONTAINS) and the arithmetic operators (+, -, *, /) over numbers, strings, lists, and temporals/durations, with checked integer arithmetic (overflow and division by zero yield Null -- eval has no per-row error channel).
Binary operator evaluation shared by the interpreter and the compiled path: string predicates (STARTS WITH / ENDS WITH / CONTAINS) and the arithmetic operators (+, -, *, /) over numbers, strings, lists, and temporals/durations, with checked integer arithmetic (overflow and division by zero yield Null -- eval has no per-row error channel).
internal/exec
The group-by aggregator: rows route to their group's accumulators (implicit group-by-the-non-aggregate-keys), then one output row per group finalizes with ordering/pagination.
The group-by aggregator: rows route to their group's accumulators (implicit group-by-the-non-aggregate-keys), then one output row per group finalizes with ordering/pagination.
internal/explain
Expression and literal rendering for the plan tree (split from render.go for the file-size norm).
Expression and literal rendering for the plan tree (split from render.go for the file-size norm).
internal/graph
Package graph is the GQL engine's seam to the graph store: the portable read surface the planner and executor bind to (port of the Rust CypherGraph trait's data methods).
Package graph is the GQL engine's seam to the graph store: the portable read surface the planner and executor bind to (port of the Rust CypherGraph trait's data methods).
internal/parser
CALL statement parsing: braced subqueries with the GQL variable-scope clause, and procedure calls with expression arguments and YIELD.
CALL statement parsing: braced subqueries with the GQL variable-scope clause, and procedure calls with expression arguments and YIELD.
internal/plan
buildSegment: lower one run of stage specs plus its projection boundary into a Segment (port of the Rust plan.rs::build_segment, cost branch hard-wired as the only strategy).
buildSegment: lower one run of stage specs plus its projection boundary into a Segment (port of the Rust plan.rs::build_segment, cost branch hard-wired as the only strategy).
internal/semantics
Auto-parameterization (port of autoparam.rs): lift constant inline node/relationship property values out of a query into numbered parameter slots, so two queries differing only in those constants -- {id: 669} vs {id: 648}, {name: 'India'} vs {name: 'China'} -- become one template that shares a cached plan.
Auto-parameterization (port of autoparam.rs): lift constant inline node/relationship property values out of a query into numbered parameter slots, so two queries differing only in those constants -- {id: 669} vs {id: 648}, {name: 'India'} vs {name: 'China'} -- become one template that shares a cached plan.
value
Comparison semantics ported from the Rust cypher crate's value.rs: the three-valued Compare/Equal used by =, <, >, IN and friends; the Kleene combinators behind AND/OR; and the genuinely total OrderCmp for ORDER BY.
Comparison semantics ported from the Rust cypher crate's value.rs: the three-valued Compare/Equal used by =, <, >, IN and friends; the Kleene combinators behind AND/OR; and the genuinely total OrderCmp for ORDER BY.
internal
bitset
Package bitset is a minimal []uint64-backed bit vector: the engine's stand-in for Rust's bitvec, backing dense bool columns and the presence bitmaps of rank/select columns.
Package bitset is a minimal []uint64-backed bit vector: the engine's stand-in for Rust's bitvec, backing dense bool columns and the presence bitmaps of rank/select columns.
ldbc
Package ldbc loads the Rust-exported LDBC SF1 expected-results fixture (rustychickpeas-ldbc task 256) and runs the Go kernels in the exact shapes it encodes, so the cross-check tests and the bench emitter share one implementation (gochickpeas task 012).
Package ldbc loads the Rust-exported LDBC SF1 expected-results fixture (rustychickpeas-ldbc task 256) and runs the Go kernels in the exact shapes it encodes, so the cross-check tests and the bench emitter share one implementation (gochickpeas task 012).
unorm
Package unorm is a self-contained Unicode normalization implementation (UAX #15): NFC, NFD, NFKC, NFKD plus the is-normalized predicate, over tables generated from the pinned UCD version (gen/main.go) -- no golang.org/x/text dependency.
Package unorm is a self-contained Unicode normalization implementation (UAX #15): NFC, NFD, NFKC, NFKD plus the is-normalized predicate, over tables generated from the pinned UCD version (gen/main.go) -- no golang.org/x/text dependency.
unorm/gen command
Table generator for internal/unorm: downloads the Unicode Character Database files for the pinned version, computes fully-recursive decompositions, the canonical composition pairs, combining classes, and per-form quick-check exception ranges, and writes tables.go.
Table generator for internal/unorm: downloads the Unicode Character Database files for the pinned version, computes fully-recursive decompositions, the canonical composition pairs, combining classes, and per-form quick-check exception ranges, and writes tables.go.
Package nodeset provides Set, the engine's node-id set: the substrate query results compose through (intersect, union, subtract).
Package nodeset provides Set, the engine's node-id set: the substrate query results compose through (intersect, union, subtract).
Package parallel provides the chunked worker-pool primitives the engine's kernels build on -- the Go stand-in for rayon's fold/reduce shape.
Package parallel provides the chunked worker-pool primitives the engine's kernels build on -- the Go stand-in for rayon's fold/reduce shape.
Block-lazy atom resolution over a SectionFetch: the first consumer-shaped slice of the working-set machinery lazy.go defers.
Block-lazy atom resolution over a SectionFetch: the first consumer-shaped slice of the working-set machinery lazy.go defers.
cmd/gencorpus command
gencorpus writes the RCPG conformance corpus using this module's own builders and writer, for the reverse-direction interop test: the Rust codec (rustychickpeas-format's go_interop test, gated on RCPG_INTEROP_CORPUS) parses these files and requires bit-exact equality with the graphs its corpus defines.
gencorpus writes the RCPG conformance corpus using this module's own builders and writer, for the reverse-direction interop test: the Rust codec (rustychickpeas-format's go_interop test, gated on RCPG_INTEROP_CORPUS) parses these files and requires bit-exact equality with the graphs its corpus defines.
internal/conformance
Package conformance rebuilds the cross-implementation conformance corpus defined by rustychickpeas-format's conformance module, using this module's own writer.
Package conformance rebuilds the cross-implementation conformance corpus defined by rustychickpeas-format's conformance module, using this module's own writer.
rrsr
Package rrsr reads and writes the RRSR record store, byte-compatible with roaringrange's RECORDS.md spec and the Rust rustychickpeas-format codec.
Package rrsr reads and writes the RRSR record store, byte-compatible with roaringrange's RECORDS.md spec and the Rust rustychickpeas-format codec.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL