Documentation
¶
Overview ¶
Package graph defines the core types and interfaces shared by every backend in the gograph module.
The package establishes a small set of contracts:
- NodeID is the compact internal identifier used by all storage backends. It is an opaque alias of uint64.
- Mapper interns arbitrary comparable user-facing identifiers to stable NodeID values, keeping the public API generic while the storage stays cache-friendly.
- Graph is the minimal directed-graph contract every backend implements. Specialised interfaces (undirected, weighted, property graphs) extend it in dedicated subpackages.
Concurrency. The interfaces declared here do not, on their own, prescribe a concurrency model: each implementation documents its own contract on its concrete types. As a rule of thumb, gograph implementations are safe for concurrent reads on an immutable snapshot, and serialise writes per backend.
Index ¶
- Constants
- Variables
- func MapperShardCount() int
- func MapperShardOf(id NodeID) uint64
- type Graph
- type IDReserver
- type Mapper
- func (m *Mapper[N]) Intern(k N) NodeID
- func (m *Mapper[N]) InternNew(k N) (id NodeID, created bool)
- func (m *Mapper[N]) InternNewHook(k N, onCreate func(NodeID)) (id NodeID, created bool)
- func (m *Mapper[N]) Len() int
- func (m *Mapper[N]) LoadFrom(entries []MapperEntry[N], next *[MapperShards]uint64) error
- func (m *Mapper[N]) Lookup(k N) (NodeID, bool)
- func (m *Mapper[N]) MaxNodeID() NodeID
- func (m *Mapper[N]) PlaceUnborn(k N, id NodeID) (placed bool, err error)
- func (m *Mapper[N]) PublishReservation(shard int, limit uint64)
- func (m *Mapper[N]) Reserve(n int)
- func (m *Mapper[N]) ReservedLimit(shard int) uint64
- func (m *Mapper[N]) ReservedLimits() [MapperShards]uint64
- func (m *Mapper[N]) Resolve(id NodeID) (N, bool)
- func (m *Mapper[N]) RestoreNext(shard int, next uint64)
- func (m *Mapper[N]) SetIDReserver(r IDReserver)
- func (m *Mapper[N]) Unplace(k N, id NodeID) bool
- func (m *Mapper[N]) Walk(fn func(NodeID, N) bool)
- func (m *Mapper[N]) Watermark() *MapperWatermark
- type MapperEntry
- type MapperWatermark
- type NodeID
Examples ¶
Constants ¶
const MapperShards = mapperShardCount
MapperShards is the number of shards of every Mapper, as a constant for fixed-size per-shard arrays.
Variables ¶
var ErrMapperEntryCorrupted = errors.New("graph: Mapper.LoadFrom entries corrupted")
ErrMapperEntryCorrupted is returned by Mapper.LoadFrom when the supplied entries violate the on-disk invariants the snapshot writer is responsible for upholding: an intra-shard index that disagrees with the natural key's hash-derived shard, an intra-shard index at or above the shard's recorded high-water mark, or a duplicate key.
var ErrMapperKeyNotPortable = errors.New("graph: mapper key type is address-dependent and cannot be persisted")
ErrMapperKeyNotPortable is returned by Mapper.LoadFrom, wrapped in ErrMapperEntryCorrupted, when the shard disagreement it detected is explained not by a damaged snapshot but by the KEY TYPE: the key carries a pointer, an unsafe.Pointer or a channel, so its value is an ADDRESS and cannot be reproduced in another process.
Such a key is unusable as a persisted natural key, and not only because of the hash. In Go, a comparable type containing a pointer compares by ADDRESS, so a key decoded by encoding.BinaryUnmarshaler into a fresh allocation is not equal to the key that was written even when it carries the same data — its identity, not merely its shard, is unreproducible. The sentinel exists so that diagnosis lands on the key type instead of on the snapshot writer or the disk, which is where "entries corrupted" alone had pointed it (rmp #2528).
var ErrMapperNotEmpty = errors.New("graph: Mapper.LoadFrom on non-empty mapper")
ErrMapperNotEmpty is returned by Mapper.LoadFrom when the caller tries to seed a Mapper that already holds at least one interned value. LoadFrom is intended for one-shot recovery initialisation against a fresh (zero-state) Mapper; reseeding a live Mapper would silently shadow its existing entries and is a programmer error.
var ErrNodeIDMismatch = errors.New("graph: node id does not match the mapper")
ErrNodeIDMismatch is returned by Mapper.PlaceUnborn when the binding it is asked to establish contradicts the mapper: the key is already bound to a different id, or the id's slot already holds a different key. During recovery it means the durable record names an id the replay cannot reproduce, which is corruption (WAL v2 step 3, docs/design-wal-v2.md §3.1).
Functions ¶
func MapperShardCount ¶
func MapperShardCount() int
MapperShardCount returns the number of independently locked shards every Mapper uses internally. Test and tooling code that needs to reason about shard placement at runtime — e.g. adversarial key generators that collapse many distinct keys into a single shard — should call this function instead of hardcoding the constant so the caller is automatically robust to future configuration changes.
func MapperShardOf ¶
MapperShardOf returns the shard index encoded in id. It is the public counterpart of [unpackNodeID] restricted to the shard component and exists so external tooling can validate placement without depending on the internal [packNodeID] layout.
Types ¶
type Graph ¶
type Graph[N comparable, W any] interface { // Order returns the number of distinct nodes currently in the graph. Order() uint64 // Size returns the number of edges currently in the graph. For // multigraphs, parallel edges count separately. Size() uint64 // Neighbours returns an iterator over the out-neighbours of n and // the weight of each connecting edge. The iterator yields no values // when n is not present in the graph. The order in which neighbours // are visited is implementation-defined. Neighbours(n N) iter.Seq2[N, W] // HasEdge reports whether an edge from src to dst is present. // It returns false when either endpoint is unknown. HasEdge(src, dst N) bool // AddNode inserts n if not already present. It is a no-op when n is // already known. Implementations return an error when a bounded // resource (for example, a sharded slot array with an explicit // upper bound) is exhausted; callers must handle that error and // stop offering further work on the affected shard. AddNode(n N) error // AddEdge inserts a directed edge from src to dst with weight w, // adding the endpoints if they are not yet present. Multigraph // implementations accept parallel edges; simple implementations // document their de-duplication policy. Implementations return an // error when a bounded resource is exhausted (see [Graph.AddNode]); // no edge is published in that case. AddEdge(src, dst N, w W) error // RemoveEdge removes the directed edge from src to dst if present. // It is a no-op when no such edge exists. The endpoints remain in // the graph. Implementations return an error, and remove nothing, when // the removal is refused — for example, a versioned implementation // refuses a removal that would overwrite another transaction's // uncommitted write. RemoveEdge(src, dst N) error }
Graph is the minimal directed-graph contract.
Implementations choose their own storage layout (adjacency list, CSR, mmap'd file, …) and document their own concurrency contract; this interface only fixes the shape callers see.
N is the user-facing node type (any comparable type). W is the edge weight type; use struct{} for unweighted graphs.
type IDReserver ¶ added in v0.16.0
type IDReserver interface {
// ReserveIDs returns once the limit of shard is at least need — a reservation
// covering every intra index below need is recorded and published — or once
// the reserver can record nothing more and has published an unlimited limit
// (math.MaxUint64). It runs synchronously on the caller's goroutine, so the
// reservations a sequence of interns produces are a function of that
// sequence alone.
ReserveIDs(shard int, need uint64)
}
IDReserver records id reservations for a Mapper (WAL v2 step 4). The mapper calls it from its interning critical section, holding the shard's write lock, so an implementation must never take a mapper lock, directly or by waiting on a goroutine that does. It publishes each reservation it records through Mapper.PublishReservation.
Implementations must be safe for concurrent use: different shards call it at the same time.
type Mapper ¶
type Mapper[N comparable] struct { // contains filtered or unexported fields }
Mapper interns user-facing identifiers of type N as compact NodeID values. Interning is stable for the lifetime of the Mapper: a value always resolves to the same NodeID and a NodeID always resolves back to the value that produced it.
Mapper is safe for concurrent use by any number of goroutines. The implementation is sharded into 256 independent stripes keyed by the hash of N, so contention only arises between goroutines operating on values that collide on the lowest 8 bits of their hash.
The zero value of Mapper is not usable; construct one with NewMapper.
Example ¶
ExampleMapper shows the core contract of a Mapper: arbitrary comparable user keys are interned to compact NodeID values, and the mapping is stable — the same key always yields the same NodeID, which resolves back to the original key.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/GoGraph/graph"
)
func main() {
m := graph.NewMapper[string]()
// Interning a key returns its NodeID; re-interning the same key
// returns the identical NodeID (the mapping is stable for the
// Mapper's lifetime).
alice := m.Intern("alice")
again := m.Intern("alice")
bob := m.Intern("bob")
// Resolve reverses the mapping back to the user key.
key, ok := m.Resolve(alice)
fmt.Println("alice stable:", alice == again)
fmt.Println("alice != bob:", alice != bob)
fmt.Println("resolve:", key, ok)
fmt.Println("interned:", m.Len())
}
Output: alice stable: true alice != bob: true resolve: alice true interned: 2
func NewMapper ¶
func NewMapper[N comparable]() *Mapper[N]
NewMapper returns a fresh, empty Mapper ready for concurrent use.
func (*Mapper[N]) Intern ¶
Intern returns the NodeID associated with k, allocating a new one on first encounter. Subsequent calls with the same value return the same NodeID. The fast path (k already interned) takes a read lock only and performs no heap allocation.
func (*Mapper[N]) InternNew ¶ added in v0.11.0
InternNew is Mapper.Intern with the answer to "did this call CREATE the node?".
created is true exactly once per key, on the call that first assigns it an id. It exists because a layer above has to record WHEN a node came into existence — MVCC needs a reader from before that instant not to see it — and the alternative, a Lookup before every Intern, puts a second map probe on the hottest write path there is, on behalf of a case that happens once per node.
Safe for concurrent use; concurrent callers racing on the same new key see exactly one created=true between them.
func (*Mapper[N]) InternNewHook ¶ added in v0.11.0
InternNewHook is Mapper.InternNew with a callback invoked, for a newly created id only, WHILE THE SHARD WRITE LOCK IS STILL HELD.
Why the hook and not a call after the return ¶
The layer above records when each node came into existence, so a reader from before that instant does not see it. Recording it after InternNew returns leaves a window in which the node is already reachable through Mapper.Walk and carries no such record — and a reader in that window treats it as having existed forever, emitting a row for a node that does not exist yet.
Publishing the record under this lock closes it: Mapper.Walk holds the same shard's read lock, so a reader that can see the id is ordered after the callback that recorded it.
onCreate must not re-enter the Mapper. It may take other locks, and the order that establishes — mapper shard, then the caller's own — must not be inverted anywhere.
func (*Mapper[N]) Len ¶
Len returns the total number of values currently interned across every shard, holes excluded. The returned count is a consistent snapshot per shard but may not reflect concurrent inserts in other shards.
func (*Mapper[N]) LoadFrom ¶
func (m *Mapper[N]) LoadFrom(entries []MapperEntry[N], next *[MapperShards]uint64) error
LoadFrom rebuilds m's internal state from a snapshot's entries and the per-shard high-water marks next (the snapshot's nodeids.bin). It is intended for one-shot recovery initialisation against a fresh (zero-state) Mapper.
The pre-conditions enforced are:
- m must be empty in every shard (ErrMapperNotEmpty otherwise).
- Each entry's NodeID, when unpacked, must yield a shard index equal to mapperShardFor(entry.Key). The writer guarantees this because it composes NodeIDs via [packNodeID] from the same hash.
- When next is non-nil, every entry's intra index must lie below next[shard]; an index at or above it is ErrMapperEntryCorrupted.
- Within a shard, no two entries may collide on the natural key or on the intra index.
Gaps are accepted (WAL v2 step 1): an intra index below a shard's high-water mark that no entry names is a HOLE — an id that was assigned and never born, which a capture leaves out of the image. Holes resolve to nothing (Mapper.Resolve false) and are skipped by Mapper.Walk.
Post-condition: a previously seeded key interns to its original NodeID; a new key in shard s receives intra index next[s] (or the highest restored index + 1 when next is nil, which is how a snapshot without nodeids.bin loads).
LoadFrom is safe for concurrent goroutines only with respect to other LoadFrom calls (which would all fail with ErrMapperNotEmpty after the first); it must not run concurrently with any Intern/Lookup/Resolve/Walk call on the same Mapper.
func (*Mapper[N]) Lookup ¶
Lookup returns the NodeID previously assigned to k and true, or the zero NodeID and false when k has not been interned. The fast path holds a read lock only and performs no heap allocation. Unlike Mapper.Intern, Lookup never mutates the Mapper, which makes it the right primitive for read-only operations (HasEdge, Neighbours, existence checks) on backends layered above the Mapper.
Example ¶
ExampleMapper_Lookup distinguishes Lookup (read-only) from Intern (which assigns a NodeID on first reference). Lookup never mutates the Mapper, so it reports whether a key has already been interned.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/GoGraph/graph"
)
func main() {
m := graph.NewMapper[string]()
m.Intern("alice")
_, known := m.Lookup("alice")
_, unknown := m.Lookup("carol")
fmt.Println("alice known:", known)
fmt.Println("carol known:", unknown)
}
Output: alice known: true carol known: false
func (*Mapper[N]) MaxNodeID ¶
MaxNodeID returns one more than the largest NodeID that has been assigned by this Mapper (holes included: it bounds the id space, not the node count). It is the natural size for an array indexed directly by NodeID (e.g. a CSR offsets array). Returns 0 when no value has been interned.
func (*Mapper[N]) PlaceUnborn ¶ added in v0.16.0
PlaceUnborn binds key k to the exact id named by a durable record (a commit marker's id annex), for recovery only (WAL v2 step 3). It reports whether it established a new binding:
- k already bound to id: no-op, placed false;
- k bound to another id, or id's slot holding another key: ErrNodeIDMismatch;
- otherwise: k takes id's slot, every free index below it in the shard becomes a hole, the shard's high-water mark rises past it, and placed is true.
An id whose shard is not k's hash shard is ErrNodeIDMismatch as well: no process could have assigned it.
Safe for concurrent use; recovery calls it from one goroutine.
func (*Mapper[N]) PublishReservation ¶ added in v0.16.0
PublishReservation raises shard's reserved limit to limit; a value below the current one is ignored, so publications may arrive in any order. limit math.MaxUint64 makes the shard unlimited. Lock-free; safe for concurrent use, including from inside the mapper's interning critical section.
func (*Mapper[N]) Reserve ¶ added in v0.3.1
Reserve pre-allocates interning capacity for an expected total of n distinct keys, spread evenly across the Mapper's shards. It is a pure capacity hint: it never assigns a NodeID, never changes the NodeID a future Mapper.Intern will assign, and never changes iteration or resolution order. Calling Reserve only reduces the number of map and slice re-growths the subsequent Intern calls incur, which is the project's "pre-size all slices and maps" mandate applied to bulk ingest. A non-positive n is a no-op.
Because keys hash uniformly across the 256 shards, the per-shard reservation is ceil(n / shardCount); a heavily skewed key distribution may still grow some shards past the hint, which is harmless. Reserve takes each shard's write lock in turn and is safe for concurrent use, though it is intended to be called once, before ingest begins, on a quiescent Mapper.
func (*Mapper[N]) ReservedLimit ¶ added in v0.16.0
ReservedLimit returns shard's reserved limit: 0 when nothing is reserved or no reserver is installed, math.MaxUint64 when the shard is unlimited. Lock-free; safe for concurrent use.
func (*Mapper[N]) ReservedLimits ¶ added in v0.16.0
func (m *Mapper[N]) ReservedLimits() [MapperShards]uint64
ReservedLimits returns every shard's reserved limit, for a checkpoint's nodeids.bin (docs/design-wal-v2.md §2.4, §3.3). An unlimited shard reads 0: its reserver can record nothing more, so no durable record can name an id issued past the shard's high-water mark, which the checkpoint takes from the mapper itself. Lock-free; safe for concurrent use.
func (*Mapper[N]) Resolve ¶
Resolve returns the value previously interned under id, or the zero value of N and false when id was not produced by this Mapper or is a hole (an id below the shard's high-water mark that names no key).
func (*Mapper[N]) RestoreNext ¶ added in v0.16.0
RestoreNext sets shard's high-water mark to next, or to the length of its reverse table when that is larger: the indices from there to next become holes the next new key skips. Recovery only (WAL v2 step 4): it applies the marks the log's reservations and its clean-close record name, which may lie below a snapshot's marks. Safe for concurrent use; recovery calls it from one goroutine.
func (*Mapper[N]) SetIDReserver ¶ added in v0.16.0
func (m *Mapper[N]) SetIDReserver(r IDReserver)
SetIDReserver installs r as the mapper's id reserver, or removes it when r is nil, and resets every shard's reserved limit to zero: the first new key of each shard then reserves through r.
Call it before the mapper is shared by concurrent interners — a store calls it at construction. A key interned concurrently with the call may be issued under the previous reserver's limits.
func (*Mapper[N]) Unplace ¶ added in v0.16.0
Unplace removes a binding Mapper.PlaceUnborn established, leaving id's slot a hole; recovery uses it to withdraw the placements of a transaction it then discards. It reports whether k was bound to id. The shard's high-water mark is not lowered. Safe for concurrent use; recovery calls it from one goroutine.
func (*Mapper[N]) Walk ¶
Walk invokes fn for every interned (NodeID, value) pair, skipping holes, taking each shard's RLock once for the whole iteration instead of once per Resolve call. Returns early when fn returns false.
Concurrency: Walk holds each shard's RLock while iterating that shard, so concurrent Intern calls on the same shard block until Walk advances past it. Concurrent Resolve calls on the same shard also block (the read lock is held for the duration of the inner loop). Use Walk for bulk export where many Resolves would otherwise dominate; prefer Resolve for individual lookups.
The callback must not re-enter this Mapper — directly or through any structure layered above it (Lookup, Intern, Resolve, Len) — while a concurrent writer may be running: a key walked in shard S re-locks shard S on Lookup, and once a writer's Intern queues on that shard's write lock, sync.RWMutex admits no new readers, so the nested read lock deadlocks the callback, the writer, and every future operation on the shard. Snapshot the (NodeID, value) pairs inside the callback and resolve any dependent state after Walk returns instead (see cypher task #1339).
Example ¶
ExampleMapper_Walk performs a bulk export of every interned (NodeID, key) pair. Walk visits each pair exactly once; the iteration order follows the Mapper's internal sharding rather than insertion order, so callers that need a stable order sort the result themselves.
package main
import (
"fmt"
"sort"
"github.com/FlavioCFOliveira/GoGraph/graph"
)
func main() {
m := graph.NewMapper[string]()
m.Intern("alice")
m.Intern("bob")
m.Intern("carol")
var keys []string
m.Walk(func(_ graph.NodeID, key string) bool {
keys = append(keys, key)
return true // returning false would stop the walk early
})
sort.Strings(keys)
fmt.Println(keys)
}
Output: [alice bob carol]
func (*Mapper[N]) Watermark ¶ added in v0.16.0
func (m *Mapper[N]) Watermark() *MapperWatermark
Watermark returns each shard's high-water mark, read shard by shard under each shard's read lock. Every per-shard mark is exact for the moment its shard was read; marks of different shards may straddle a concurrent intern. A capture reads it just after its instant, so every id assigned at the instant is covered (lpg.Graph.BeginCaptureRead).
It allocates one fixed-size value (256 counts) and is O(shards).
Safe for concurrent use.
type MapperEntry ¶
type MapperEntry[N comparable] struct { Key N ID NodeID }
MapperEntry describes one (NodeID -> natural key) pair as serialised by the snapshot writer. The NodeID is packed so the unpacked shard index matches mapperShardFor(Key), and the intra-shard index agrees with the slot the key would occupy if all entries for that shard were interned in NodeID-ascending order. The snapshot writer guarantees both invariants by enumerating pairs via Mapper.Walk.
type MapperWatermark ¶ added in v0.16.0
type MapperWatermark struct {
// contains filtered or unexported fields
}
MapperWatermark records each shard's high-water mark — the intra index its next new key would receive — when it was taken. Below it lie every id the shard has assigned and its holes (ids reserved and never born, WAL v2 step 1). Interning is append-only within a shard, so the ids a shard assigned before the watermark are exactly those whose intra-shard index is below the recorded count: MapperWatermark.Covers answers "was this id interned when the watermark was taken" exactly, from the id alone.
It exists for an MVCC snapshot capture (rmp #2991). A capture must carry every id interned at its instant and no id interned later, and the per-id birth records cannot answer that once an aborted creation has been withdrawn: the withdrawn id then looks as old as a node whose record was reclaimed. The watermark taken at the instant answers it without consulting any record.
Concurrency: a MapperWatermark is immutable once returned and safe for concurrent reads.
func (*MapperWatermark) Covers ¶ added in v0.16.0
func (w *MapperWatermark) Covers(id NodeID) bool
Covers reports whether id had been assigned when w was taken: its intra-shard index is below the high-water mark w recorded for its shard. It is true for a hole, which is harmless: a hole names no key, so no walk reaches it.
Safe for concurrent use.
func (*MapperWatermark) Next ¶ added in v0.16.0
func (w *MapperWatermark) Next() [MapperShards]uint64
Next returns the per-shard high-water marks, indexed by shard, for a snapshot's nodeids.bin.
type NodeID ¶
type NodeID uint64
NodeID is the compact internal identifier assigned by a Mapper to a user-facing node value. It is an opaque uint64; callers must not interpret its bit layout, which is an implementation detail of the Mapper that produced it.
The zero value of NodeID is a valid identifier (the first node a mapper interns); use the bool returned by Mapper.Resolve to distinguish "unknown" from "first node".
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package adjlist provides a mutable, sharded adjacency-list backend for the gograph module.
|
Package adjlist provides a mutable, sharded adjacency-list backend for the gograph module. |
|
Package csr provides an immutable Compressed Sparse Row (CSR) view of a graph for read-mostly analytical workloads.
|
Package csr provides an immutable Compressed Sparse Row (CSR) view of a graph for read-mostly analytical workloads. |
|
Package generation publishes immutable graph snapshots (typically csr.CSR views) under a refcount-protected pointer so readers can observe a consistent generation while a new one is being prepared in the background.
|
Package generation publishes immutable graph snapshots (typically csr.CSR views) under a refcount-protected pointer so readers can observe a consistent generation while a new one is being prepared in the background. |
|
Package index coordinates the secondary indexes attached to a labelled property graph.
|
Package index coordinates the secondary indexes attached to a labelled property graph. |
|
btree
Package btree provides an order-preserving property index over a constraints.Ordered value type, answering range predicates against the NodeIDs that carry each value.
|
Package btree provides an order-preserving property index over a constraints.Ordered value type, answering range predicates against the NodeIDs that carry each value. |
|
count
Package count holds the derived, non-durable relationship count-store that backs exact cardinality estimates for the Cypher planner (design docs/count-store-design.md, task #2082).
|
Package count holds the derived, non-durable relationship count-store that backs exact cardinality estimates for the Cypher planner (design docs/count-store-design.md, task #2082). |
|
hash
Package hash provides a sharded hash index from arbitrary comparable property values to the set of NodeIDs that carry them, represented as a 64-bit Roaring bitmap.
|
Package hash provides a sharded hash index from arbitrary comparable property values to the set of NodeIDs that carry them, represented as a 64-bit Roaring bitmap. |
|
label
Package label provides a Roaring-bitmap-backed inverted index from label identifiers to the NodeIDs that carry them.
|
Package label provides a Roaring-bitmap-backed inverted index from label identifiers to the NodeIDs that carry them. |
|
stats
Package stats holds the best-effort, approximate planner statistics that back the Cypher optimiser's cardinality estimates for single-column predicates (design docs/statistics-design.md, tasks #2097 / #2098).
|
Package stats holds the best-effort, approximate planner statistics that back the Cypher optimiser's cardinality estimates for single-column predicates (design docs/statistics-design.md, tasks #2097 / #2098). |
|
io
|
|
|
csv
Package csv reads and writes graphs as edge lists in CSV format.
|
Package csv reads and writes graphs as edge lists in CSV format. |
|
dot
Package dot writes graphs in the Graphviz DOT format (https://graphviz.org/doc/info/lang.html).
|
Package dot writes graphs in the Graphviz DOT format (https://graphviz.org/doc/info/lang.html). |
|
graphml
Package graphml reads and writes graphs in the GraphML XML dialect (http://graphml.graphdrawing.org/).
|
Package graphml reads and writes graphs in the GraphML XML dialect (http://graphml.graphdrawing.org/). |
|
jsonl
Package jsonl reads and writes graphs in newline-delimited JSON (NDJSON / JSON Lines) format.
|
Package jsonl reads and writes graphs in newline-delimited JSON (NDJSON / JSON Lines) format. |
|
Package lpg implements the Labelled Property Graph model on top of the github.com/FlavioCFOliveira/GoGraph/graph/adjlist mutable adjacency-list backend.
|
Package lpg implements the Labelled Property Graph model on top of the github.com/FlavioCFOliveira/GoGraph/graph/adjlist mutable adjacency-list backend. |
|
schema
Package schema declares the optional type schema for a labelled property graph: which labels exist, which property keys exist, which lpg.PropertyKind each property carries, and which properties each label requires.
|
Package schema declares the optional type schema for a labelled property graph: which labels exist, which property keys exist, which lpg.PropertyKind each property carries, and which properties each label requires. |
|
Package mvcc holds the timestamp and visibility primitives the versioned stores share.
|
Package mvcc holds the timestamp and visibility primitives the versioned stores share. |
|
Package query provides a fluent, type-safe programmatic API for expressing MATCH-style pattern queries against a labelled property graph snapshot.
|
Package query provides a fluent, type-safe programmatic API for expressing MATCH-style pattern queries against a labelled property graph snapshot. |