graph

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package graph holds Mesh's in-memory knowledge graph. The node/edge shape is lifted from dockyard's internal/knowledge graph and adapted for markdown: identity is the frontmatter id (node id "note:<id>"), never the file path, so a rename never rots an edge or an agent citation (spec section 3.6).

Index

Constants

View Source
const (
	ConfExtracted = "EXTRACTED"
	ConfInferred  = "INFERRED"
	ConfAmbiguous = "AMBIGUOUS"
)

Edge confidence levels (from the dockyard/graphify extraction model).

Variables

This section is empty.

Functions

func Tokenize

func Tokenize(s string) []string

Tokenize lowercases and splits on non-alphanumeric runs, dropping tokens shorter than 2 runes and stopwords. The unicode boundaries match FTS5's unicode61 tokenizer so the two keyword signals share term shape.

Types

type Edge

type Edge struct {
	Source          string
	Target          string
	Relation        string // contains|references|tagged|...
	Confidence      string
	ConfidenceScore float64
	Weight          float64
	SourceLoc       string
}

type Graph

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

Graph is a concurrent-safe adjacency list. Reads take the RLock; the index builder is the only writer in M0.

func New

func New() *Graph

func NewSized

func NewSized(n int) *Graph

NewSized preallocates the maps for a graph expected to hold about n notes. A note contributes roughly one note node plus a handful of heading/tag nodes and edges, so the hints below avoid the repeated rehashing that dominates a from-scratch rebuild of a large vault. Hints are advisory; the graph still grows past them. n <= 0 builds with no hint (the small-vault default).

func (*Graph) AddEdge

func (g *Graph) AddEdge(e Edge)

AddEdge inserts a unique (source, target, relation) edge and bumps the degree of whichever endpoints already exist.

func (*Graph) AddNode

func (g *Graph) AddNode(n *Node)

AddNode inserts a node, or enriches a previously bare reference node with real path/label data once its owning file is parsed.

func (*Graph) CountByKind

func (g *Graph) CountByKind() map[string]int

func (*Graph) DetectCommunities

func (g *Graph) DetectCommunities(maxRounds int) int

DetectCommunities partitions the graph with the Louvain method (greedy modularity maximization) and writes a community id onto every node. Louvain beats the old label-propagation default on the quality that matters here: it does not collapse weakly-bridged clusters into one giant community, so the orientation tools and the web-graph coloring show meaningful groups. The result is deterministic (nodes are processed in sorted-id order, ties never move a node) and communities are renumbered 0..k-1 by their smallest member id, so the output shape is identical to the previous implementation; only the groupings improve. maxRounds caps the local-moving passes per level (default 20). Returns the number of communities.

func (*Graph) EdgeCount

func (g *Graph) EdgeCount() int

func (*Graph) Neighbors

func (g *Graph) Neighbors(id string) []Edge

Neighbors returns a copy of the outbound edges for id.

func (*Graph) NewRanker

func (g *Graph) NewRanker() *Ranker

NewRanker builds the inverted statistics over every note node's label+attrs.

func (*Graph) Node

func (g *Graph) Node(id string) (*Node, bool)

func (*Graph) NodeCount

func (g *Graph) NodeCount() int

func (*Graph) Nodes

func (g *Graph) Nodes() []*Node

func (*Graph) RecomputeDegrees

func (g *Graph) RecomputeDegrees()

RecomputeDegrees sets every node's Degree from its adjacency lists, making the value independent of node/edge insertion order. AddEdge only bumps endpoints that already exist at insertion time, so a graph assembled by interleaving AddNode and AddEdge (BuildGraph: a references edge to a not-yet-added later note never counts that note's inbound degree) would otherwise disagree with one built nodes-first (LoadGraph). Call this once after the graph is fully assembled so both paths agree.

func (*Graph) RefsTo

func (g *Graph) RefsTo(id string) []Edge

RefsTo returns a copy of the inbound edges pointing at id.

type Node

type Node struct {
	ID        string // note:<frontmatter-id> | tag:<name> | note:<id>#<anchor>
	Kind      string // note|heading|tag|external|...
	Label     string
	NoteID    string // owning note's frontmatter id
	NotePath  string // denormalized for fast file open; refreshed on rename
	Anchor    string // heading slug for fetch-by-anchor
	SourceLoc string // "L<line>" for the editor deep link
	Community int
	Attrs     map[string]any
	Degree    int
}

type Ranker

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

Ranker precomputes corpus statistics over the scorable (note) nodes once, so per-query scoring is O(queryTerms x candidates) instead of arachne's O(corpus)-per-call. Rebuild it whenever the graph changes.

func (*Ranker) Score

func (r *Ranker) Score(query string, limit int) []ScoredNode

Score ranks note nodes against the query by BM25 over label+attrs. Returns nodes with a positive score, sorted by score desc with node id as the deterministic tiebreak.

type ScoredNode

type ScoredNode struct {
	Node  *Node
	Score float64
}

ScoredNode pairs a node with its BM25 relevance (higher is better).

Jump to

Keyboard shortcuts

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