Skip to main content

Crate weavatrix_graph

Crate weavatrix_graph 

Source
Expand description

§Weavatrix Graph

CI crates.io docs.rs MIT MSRV

The deterministic graph core behind Weavatrix repository intelligence.

weavatrix-graph is the protocol-independent Rust library that gives Weavatrix its typed, evidence-carrying repository graph. It is also usable by repository analyzers, architecture tools, dependency explorers, and other applications without depending on the Weavatrix engine or MCP product.

The crate owns graph integrity and serialization. It does not walk files, parse programming languages, execute commands, access the network, or provide an MCP/CLI transport.

§Properties

  • typed nodes and edges with custom extension kinds;
  • strongly typed, non-empty node identifiers;
  • source spans, optional language labels, evidence kind, confidence, and extractor provenance;
  • structured node and edge attributes for parser-specific metadata;
  • deterministic node and edge order independent of insertion order;
  • compact numeric endpoints with incoming and outgoing CSR indexes;
  • an optional direct-neighbor traversal cache with automatic, fast, bit-packed, and succinct layouts, reusable eager/lazy walks, and no new dependency;
  • a mutable insertion-order graph with generation-stable node and edge keys;
  • allocation-reusing lazy BFS, DFS, and generic Dijkstra iterators, early stopping, DFS events, and reusable workspaces;
  • generic checked integer and finite floating-point path costs through the Measure trait;
  • BFS, DFS, reachability, unweighted shortest paths, Dijkstra, A*, signed Bellman-Ford, filtered SCC, weak components, condensation DAGs, cycle discovery, topological sort, MST, and Dinic maximum flow;
  • standard PageRank with dangling-mass redistribution, control-flow dominators, dominance frontiers, deterministic DAG longest paths and topological generations, and DAG transitive reduction plus closure;
  • Floyd-Warshall and Johnson all-pairs shortest paths, bounded simple and K-shortest paths, bounded elementary circuit enumeration, undirected bridges and articulation points, iterative vertex-biconnected edge blocks, exact eccentricity/radius/diameter/center/periphery analytics, deterministic multigraph-safe chain decomposition, checked weighted Stoer-Wagner global min-cut, and label-aware graph/subgraph isomorphism;
  • bidirectional Dijkstra and queue-based SPFA with checked arithmetic and reachable-negative-cycle reporting;
  • bipartite partitioning, Hopcroft-Karp maximum bipartite matching, and bounded Bron-Kerbosch maximal-clique enumeration;
  • exact general-graph maximum matching with Edmonds blossoms and deterministic DSATUR coloring;
  • deterministic Eades feedback-arc approximation and a multi-start metric-closure Steiner-tree approximation that retains the standard two-approximation candidate;
  • degree, closeness, node/edge betweenness, Katz, eigenvector, and HITS hub/authority centrality, plus k-core, cycle-basis, and deterministic label-propagation community analysis;
  • Edmonds-Karp, push-relabel, min-cost maximum flow, and Prim spanning forests alongside Dinic and Kruskal;
  • zero-copy reversed, edge-filtered, and induced-subgraph views, plus complement and union operators;
  • edge-kind, evidence, extractor, confidence, and caller-defined traversal filters;
  • automatic Floyd-Warshall/Johnson selection with the selected strategy exposed to callers;
  • deterministic DOT, Graph6, and GraphML topology interchange;
  • undirected incidence CSR, a generic dense matrix, a bit-packed adjacency matrix, and deterministic seeded graph generators;
  • generic directed and undirected payload graphs alongside the evidence-carrying model;
  • optional Rayon batch traversal, shortest-path queries, Johnson APSP, closeness, and node/edge betweenness centrality;
  • a generic mutable payload graph with compact intrusive adjacency, generation keys, mapping, compaction, and an acyclic invariant wrapper;
  • a GraphMap-style keyed payload index backed by generation-stable handles, plus a mutable undirected payload graph with O(1) intrusive incidence updates;
  • no_std + alloc support with the default std feature kept for faster hash-backed rich graph construction;
  • idempotent insertion of identical nodes and edges;
  • rejection of conflicting nodes, dangling edges, and invalid source spans;
  • validated deserialization that cannot bypass graph invariants;
  • compatibility conversion from Weavatrix’s legacy { nodes, links } graph;
  • no unsafe code in the default or featureless no_std build; the opt-in unsafe-fast feature is confined to audited bit-matrix and parallel-CSR primitives;
  • the default build has one runtime dependency, serde, while the optional rayon feature is isolated from the core.

§Architecture

The crate is a layered graph core, not a monolithic graph type. Dependencies flow from stable contracts toward specialized behavior:

LayerModulesResponsibility
Evidence modelattribute, error, filter, kind, modelTyped identities, kinds, provenance, confidence, spans, attributes, and validation errors
Graph viewstopology, undirected, matrix, view, operatorCompact endpoints and the generic directed/undirected view contracts algorithms consume
AlgorithmsalgoTraversal, paths, components, cuts, flow, ranking, matching, and structural analysis over views
Storagegraph, working, payload, traversal_cacheCanonical evidence snapshots, mutable builders, stable payload graphs, and derived traversal indexes
Interchangeformat, generator, legacyDeterministic wire formats, seeded graph construction, and compatibility conversion
Public facadelib.rsStable crate-root re-exports without owning domain logic

Module trees use one idiomatic source form: nested modules live under foo/mod.rs, never beside a competing foo.rs. The strict .weavatrix/architecture.json contract enforces a 300-line file budget, 100-line function budget, zero runtime dependency cycles, and no exception or ratchet baseline. tests/architecture.rs independently guards file size, single-form module layout, focused facades, dependency uniqueness, and wire-kind uniqueness.

The default and no_std paths forbid unsafe code. The explicitly enabled unsafe-fast feature remains isolated to audited matrix and CSR primitives; it does not change the public layering or graph invariants.

§Layered graph contracts

The crate keeps storage contracts separate instead of making one graph type pay for every feature:

TypePurposeOrdering and validation
TopologyImmutable directed numeric graphPreserves edge order, validates compact endpoints, builds outgoing and incoming CSR
TraversalCacheOptional derived neighbor topologyKeeps both directions and exact adjacency order; selects direct, bit-packed, or succinct storage
WorkingGraphFast rich mutation and incremental extractionPreserves insertion order, validates local invariants once, uses generation-stable keys
GraphImmutable evidence snapshot and wire formatSorts, deduplicates, validates, and emits canonical output
UndirectedTopologyGeneral-purpose undirected algorithmsCompact incidence CSR with parallel-edge and self-loop support
DenseMatrix<T>Small dense graphsFixed-size O(1) edge lookup without sparse-graph overhead
BitMatrixLarge dense boolean relationsOne bit per possible directed edge with safe O(1) lookup
PayloadGraph<N, E>Arbitrary application payloadsValidated topology plus separately owned node and edge values
StablePayloadGraph<N, E>Generic mutable application graphGeneration-checked stable keys, compact intrusive adjacency, payload mapping, and immutable freeze()
KeyedPayloadGraph<K, N, E>Domain-key lookup and mutationHash-backed under std, deterministic tree-backed under no_std, stable handles for algorithms
StableUndirectedPayloadGraph<N, E>Mutable undirected multigraphGeneration-checked node/edge keys, intrusive double-ended incidence, parallel edges, self-loops, retargeting, and compact freeze()
AcyclicPayloadGraph<N, E>Mutable DAG workflowsRejects cycle-creating inserts and edge retargeting

WorkingGraph::freeze() is the explicit boundary between extraction and publication. It returns the canonical Graph plus a stable-to-compact index map. Graph::try_from_sorted_nodes avoids rebuilding the node-id map when an extractor already emits unique sorted nodes, while Graph::try_from_sorted_parts is the fastest fully canonical input path.

KeyedPayloadGraph keeps application keys out of algorithm internals: lookups resolve to StableNodeKey, while its inner StablePayloadGraph implements the shared graph views. StableUndirectedPayloadGraph implements IndexUndirectedGraphView directly, so BCC, MST, matching, coloring, and other undirected algorithms run before or after mutation without an adapter.

§Example

use weavatrix_graph::{
    Confidence, Edge, EdgeKind, EvidenceKind, GraphBuilder, Node, NodeKind,
    Provenance,
};

let repository = Node::new("repo:demo", "demo", NodeKind::Repository)?;
let file = Node::new("file:src/lib.rs", "src/lib.rs", NodeKind::File)?;

let mut builder = GraphBuilder::new();
builder.add_node(repository.clone())?;
builder.add_node(file.clone())?;
builder.add_edge(Edge::new(
    repository.id,
    file.id,
    EdgeKind::Contains,
    Provenance::new("example", EvidenceKind::Parsed, Confidence::High)?,
))?;

let graph = builder.build()?;
assert_eq!(graph.node_count(), 2);
assert_eq!(graph.edge_count(), 1);

Algorithms use GraphView/IndexGraphView, so the same call works with a canonical Graph, a numeric Topology, or a mutable WorkingGraph. Filtering stays outside the topology and can inspect the evidence payload:

use weavatrix_graph::{
    Confidence, Direction, EdgeFilter, EdgeKind, EvidenceKind, Graph,
    bfs_filtered,
};

let Some(start) = graph.node_index("repo:demo") else {
    return Ok(());
};
let filter = EdgeFilter::new()
    .with_kind(EdgeKind::Contains)
    .with_evidence(EvidenceKind::Parsed)
    .with_minimum_confidence(Confidence::High);

let reachable = bfs_filtered(graph, start, Direction::Outgoing, |index| {
    graph.edge_at(index).is_some_and(|edge| filter.matches(edge))
});
assert!(!reachable.is_empty());

Component algorithms accept the same pure edge predicate. Condensation records the original component membership and produces a compact, deduplicated DAG:

use weavatrix_graph::{
    EdgeEndpoints, NodeIndex, Topology, condensation_filtered,
    strongly_connected_components_filtered,
};

let topology = Topology::try_from_edges(
    3,
    [(0, 1), (1, 0), (1, 2)].map(|(source, target)| {
        EdgeEndpoints::new(NodeIndex::new(source), NodeIndex::new(target))
    }),
)?;
let without_back_edge = |edge: weavatrix_graph::EdgeIndex| edge.index() != 1;

let components = strongly_connected_components_filtered(
    &topology,
    without_back_edge,
);
let condensed = condensation_filtered(&topology, without_back_edge)?;
assert_eq!(components.len(), 3);
assert_eq!(condensed.topology().node_count(), 3);

Advanced algorithms retain the same index/view contract. A* accepts an admissible heuristic, Bellman-Ford reports checked signed overflow and reachable negative cycles, and PageRank returns values in deterministic graph-node order:

use weavatrix_graph::{
    EdgeEndpoints, NodeIndex, Topology, astar, dominators, page_rank,
};

let graph = Topology::try_from_edges(
    4,
    [(0, 1), (0, 2), (1, 3), (2, 3)].map(|(source, target)| {
        EdgeEndpoints::new(NodeIndex::new(source), NodeIndex::new(target))
    }),
)?;
let weights = [2_u64, 5, 2, 1];
let Some(path) = astar(
    &graph,
    NodeIndex::new(0),
    NodeIndex::new(3),
    |edge| weights[edge.index()],
    |_| 0,
) else {
    return Ok(());
};
assert_eq!(path.total_cost(), 4);
assert_eq!(page_rank(&graph, 0.85, 20)?.len(), 4);
assert!(dominators(&graph, NodeIndex::new(0)).is_some());

All potentially exponential enumeration APIs require a caller-provided result limit and report truncation. Isomorphism accepts node and edge predicates, so architecture tools can match semantic kinds without coupling the graph crate to one language model:

use weavatrix_graph::{
    EdgeEndpoints, NodeIndex, SubgraphMode, Topology, johnson_all_pairs,
    subgraph_isomorphisms,
};

let graph = Topology::try_from_edges(
    3,
    [(0, 1), (1, 2)].map(|(source, target)| {
        EdgeEndpoints::new(NodeIndex::new(source), NodeIndex::new(target))
    }),
)?;
let paths = johnson_all_pairs(&graph, |_| 1)?;
assert_eq!(paths.distance(NodeIndex::new(0), NodeIndex::new(2)), Some(2));

let matches = subgraph_isomorphisms(
    &graph,
    &graph,
    SubgraphMode::Induced,
    1,
    |left, right| left == right,
    |_, _| true,
);
assert_eq!(matches.mappings().len(), 1);

Biconnected and chain analysis are iterative and preserve original edge IDs. Both treat parallel edges and self-loops explicitly. Exact distance analytics return None for an empty or disconnected accepted-edge graph rather than inventing finite metrics. HITS ranks topological relationships rather than evidence multiplicity: equal endpoint pairs are deduplicated after the semantic edge predicate runs once per edge.

use weavatrix_graph::{
    EdgeEndpoints, NodeIndex, Topology, UndirectedTopology,
    biconnected_components, chain_decomposition, distance_analytics, hits,
    stoer_wagner_min_cut, undirected_edge_betweenness_centrality,
};

let edges = [(0, 1), (1, 2), (2, 0), (1, 3)].map(|(source, target)| {
    EdgeEndpoints::new(NodeIndex::new(source), NodeIndex::new(target))
});
let undirected = UndirectedTopology::try_from_edges(4, edges)?;
let blocks = biconnected_components(&undirected);
assert_eq!(blocks.component_count(), 2);
assert_eq!(blocks.articulation_points(), &[NodeIndex::new(1)]);
let Some(distances) = distance_analytics(&undirected) else {
    return Ok(());
};
assert_eq!(distances.diameter(), 2);
assert_eq!(distances.center(), &[NodeIndex::new(1)]);
let chains = chain_decomposition(&undirected);
assert_eq!(chains.chain_count(), 1);
let edge_scores = undirected_edge_betweenness_centrality(&undirected, true);
assert_eq!(edge_scores.len(), 4);
let Some(cut) = stoer_wagner_min_cut(&undirected, |_| 1_u64)? else {
    return Ok(());
};
assert_eq!(cut.weight(), 1);
assert_eq!(cut.partition(), &[NodeIndex::new(3)]);

let directed = Topology::try_from_edges(4, edges)?;
let scores = hits(&directed, 100, 1e-10)?;
assert!(scores.hub(NodeIndex::new(1)).is_some());

§P2 storage, interchange, and portability

all_pairs_auto snapshots every accepted edge weight once, selects Floyd-Warshall for small or dense graphs and Johnson for sparse graphs, and returns the chosen AllPairsStrategy with the result. Explicit algorithms remain available when an application already knows the best strategy.

Interchange intentionally targets deterministic topology rather than pretending to support every dialect:

  • DOT reads and writes a strict numeric directed/undirected subset and ignores attributes;
  • Graph6 supports simple undirected graphs and rejects loops and parallel edges;
  • GraphML preserves graph direction and node declaration order while rejecting ports, hyperedges, and per-edge direction overrides.

All decoders validate endpoint references and rebuild the crate’s canonical topology indexes. PayloadGraph<N, E> and UndirectedPayloadGraph<N, E> attach arbitrary payloads without weakening those topology invariants.

The crate defaults to std. Embedded and WASM consumers can disable default features for a real no_std + alloc build:

[dependencies]
weavatrix-graph = { version = "0.6", default-features = false }

Parallel batches are explicit and optional:

[dependencies]
weavatrix-graph = { version = "0.6", features = ["rayon"] }

Large topology construction can select a measured sequential/Rayon crossover while preserving stable edge indexes and adjacency order:

let topology = Topology::try_from_edges_auto(2, edges)?;

try_from_edges_parallel always uses the safe stable-order Rayon builder. try_from_edges_parallel_unordered keeps edge identity but leaves node-local adjacency order unspecified. The automatic builder uses sequential construction below 1.5 million edges, where scheduling and atomic setup usually cost more than they save.

Traversal-heavy callers can derive a separate cache without weakening stable edge identity or evidence storage:

let cache = topology.traversal_cache(); // speed-aware Auto policy
let mut workspace = TraversalCacheWorkspace::new();
let visited = cache.bfs_with_workspace(
    NodeIndex::new(0),
    Direction::Outgoing,
    &mut workspace,
);
assert_eq!(visited.len(), 2);

let compact = topology.traversal_cache_with(TraversalStorage::Compact);
assert_eq!(compact.edge_count(), 1);

Fast stores direct u32 neighbors and offsets. Balanced bit-packs neighbor ids while retaining direct offsets. Compact adds Elias-Fano monotone offsets and automatically uses block-local frame-of-reference neighbor packing only when its exact encoded size beats global packing. Auto chooses Balanced only when it saves at least 12.5%; otherwise it keeps Fast. All modes preserve parallel edges, self-loops, and node-local adjacency order. Graph exposes the same two convenience methods, and From<&Topology> / From<&Graph> are available for generic construction.

bfs_batch_parallel and dijkstra_batch_parallel preserve query order and the same deterministic result contract as their sequential counterparts. They are intended for batches large enough to amortize scheduling, not as replacements for a single small query.

Bit-matrix lookup has an additional, separately auditable performance feature:

[dependencies]
weavatrix-graph = { version = "0.6", features = ["unsafe-fast"] }

The default BitMatrix::contains remains fully safe. With unsafe-fast, contains_fast keeps a safe API and validates both endpoints before one unchecked word access. contains_unchecked removes endpoint checks too and is an unsafe fn: callers must guarantee that both indexes are inside the matrix. The same feature exposes try_from_edges_parallel_fast and its unordered variant. Their public API remains safe; an isolated scatter backend writes validated edge slots directly and reuses atomic cursor storage as final offsets. Enabling the feature never silently changes the behavior of contains.

§Extension Kinds

Known relation and node kinds are enum variants. Ecosystem-specific kinds remain forward-compatible through Custom values. Language taxonomies intentionally belong to analyzers, not the graph core; nodes carry language as a validated string label.

use weavatrix_graph::NodeKind;

let kind = NodeKind::custom("terraform_resource")?;
assert_eq!(kind.as_str(), "terraform_resource");

§Weavatrix compatibility

The core graph format intentionally keeps canonical nodes and edges, but the crate can ingest the current JavaScript Weavatrix { nodes, links } shape:

use weavatrix_graph::{Graph, LegacyGraph};

let legacy: LegacyGraph = serde_json::from_str(r#"{
  "nodes": [
    { "id": "src/lib.rs", "label": "lib.rs" },
    { "id": "src/lib.rs#entry@1", "label": "entry()" }
  ],
  "links": [
    {
      "source": "src/lib.rs",
      "target": "src/lib.rs#entry@1",
      "relation": "contains",
      "confidence": "EXTRACTED"
    }
  ],
  "edgeTypesV": 2,
  "edgeProvenanceV": 1
}"#)?;

let graph: Graph = legacy.into_graph("weavatrix-js")?;
assert_eq!(graph.edge_count(), 1);

Legacy metadata such as line, compileOnly, typeOnly, specifier, usage, source_range, and unknown extension fields is preserved as structured attributes.

§Benchmarks

The repository includes benchmark harnesses for graph construction, indexed queries, JSON serialization, validated deserialization, and dev-only comparisons with petgraph 0.8.3 and graaf 0.112.0:

cargo bench --locked

Unless a section states otherwise, each workload runs two warmups and 11 measured iterations. The tables below use the median of five independent harness medians on Windows 11 with Rust 1.97.1. They compare equal contracts where possible and label preprocessing explicitly.

§Rich evidence construction

10,000 nodes and 30,000 evidence-carrying edges:

ModeLibraryMedian
Unsorted canonical snapshotweavatrix-graph Graph40.725 ms
Sorted canonical snapshotweavatrix-graph Graph23.427 ms
Validated mutable appendweavatrix-graph WorkingGraph35.362 ms
Payload append, no canonicalizationpetgraph adapter18.372 ms
Mutable append plus canonical freeze()weavatrix-graph47.199 ms

The petgraph adapter resolves string ids and clones the same payload but does not validate, sort, or deduplicate it. WorkingGraph remains slightly faster than full canonical construction while validating local invariants. freeze() is reported separately because it adds canonical sorting, evidence deduplication, and immutable CSR construction. At repository scale the sorted canonical implementation amortizes those guarantees and moves ahead of the narrower adapter; see the 200,000 / 1,000,000 table below.

§Compact dual CSR

10,000 numeric nodes and 30,000 edges:

ModeLibraryMedian
Arbitrary input, endpoint validation, both CSR directionsweavatrix-graph0.365 ms
Two CSR builds from caller-provided pre-sorted directionspetgraph0.463 ms
Sorting/dedup plus both CSR buildspetgraph1.699 ms

The pre-sorted petgraph row deliberately excludes preparing two differently sorted edge arrays. It is retained because that narrower contract can be useful when a caller already owns both orders.

§Algorithms

10,000 nodes and 30,000 edges, except maximum flow at 1,000/5,000:

Algorithmweavatrix-graphpetgraph
BFS0.107 ms0.157 ms
Strongly connected components0.474 ms0.650 ms
Dijkstra to one target0.913 ms0.960 ms
Minimum spanning forest1.288 ms1.856 ms
Dinic maximum flow0.322 ms0.379 ms

Deterministic randomized differential tests also compare reachability, shortest path existence and cost, SCC partitions, cycle status, topological feasibility, MST weight, and maximum-flow value against petgraph.

§Repository scale: 200,000 nodes and 1,000,000 edges

scale_graph_competitors models files as nodes and deterministic dependency relations as directed edges. Each independent process performs one warmup and five measured iterations; the table is the median of five process medians. Every process asserts exact node and edge counts, equal reachable counts, equal SCC partitions, and the same target distance before reporting timings.

Contractweavatrix-graphCompetitorResult
Dual CSR from arbitrary unique endpoints14.391 mspetgraph adapter 78.735 ms5.47x faster
Narrow baseline: both directions pre-sorted for petgraph14.391 mspetgraph 12.895 mspetgraph 11.6% faster
Mutable append, no reverse CSR or canonicalizationpetgraph 9.934 ms / graaf 30.969 msnarrower contract
BFS, materialized reachable nodes13.026 mspetgraph 49.606 ms / graaf 34.896 ms3.81x / 2.68x faster
Strongly connected components92.304 mspetgraph 316.340 ms3.43x faster
Dijkstra to one target69.190 mspetgraph 102.050 ms1.47x faster
Rich evidence snapshot from sorted owned payloads623.691 mspetgraph adapter 644.840 ms3.4% faster

The generated workload contains no duplicate endpoint pair. Weavatrix validates the arbitrary endpoints and builds both directions by linear counting placement while retaining stable original edge indexes and support for parallel edges. The equal-input petgraph adapter must produce, sort, and deduplicate two edge orders for its simple CSR contract. Its pre-sorted row receives both orders already prepared and therefore measures a deliberately narrower input contract. Mutable append is shown only as a lower-bound reference because it does not build an immutable dual-CSR snapshot.

The rich adapter resolves the same string ids and moves the same node/edge payloads, but does not validate payloads, check canonical ordering, deduplicate evidence, or build reverse CSR. The 6.2% construction premium is therefore the remaining scale tradeoff for the stronger snapshot contract, not an algorithmic correctness gap.

Median peak working set from three fresh processes, including input generation, temporary construction storage, allocator high-water state, and the live result:

Constructionweavatrix-graphCompetitor
Compact dual CSR37.9 MiBpetgraph dual CSR 68.5 MiB
Mutable adjacencypetgraph 44.9 MiB / graaf 47.5 MiB
Rich evidence graph, ownership transferred377.1 MiBpetgraph adapter 585.8 MiB

Peak working set is a capacity-planning number, not the retained deep size of the graph. Reproduce the scale run with:

cargo bench --locked --all-features --bench scale_graph_competitors

§Parallel construction at 1M, 10M, and 100M edges

This follow-up compares parallel with parallel. It ran locally on Windows 11, Rust 1.97.1, and an Intel Core Ultra 7 255U with 14 Rayon workers. The deterministic input has five outgoing edges per node. The 1M and 10M rows are medians of nine and seven measured builds; 100M is a three-build median after one warmup.

Nodes / edgesweavatrix-graphgraph_builder 0.4.2 RayonResult
200k / 1M, auto stable14.165 ms15.223 msWeavatrix 7.5% faster
2M / 10M, safe stable178.705 ms115.697 msnarrower competitor 35.3% faster
2M / 10M, unsafe-fast stable117.888 ms115.697 mswithin 1.9%
20M / 100M, unsafe-fast stable1.705 s1.518 snarrower competitor 12.3% faster
20M / 100M, unsafe-fast unordered1.662 s1.518 snarrower competitor 9.5% faster

Both sides ingest arbitrary endpoint order, validate or infer bounds, and build incoming plus outgoing CSR. The contracts are not identical: weavatrix-graph::Topology also retains the original endpoint array, stable EdgeIndex identity, parallel-edge identity, and, in stable modes, deterministic node-local edge order. graph_builder stores direct neighbor targets and uses internal unchecked scatter writes. Its row is a throughput lower bound, not evidence that the stronger snapshot is incorrect. Every Weavatrix stable build is asserted equal to the sequential topology before timing.

The original evidence topology exposes the cost of resolving an EdgeIndex through the endpoint array:

Nodes / edgesWeavatrix evidence CSRDirect-neighbor CSRResult
200k / 1M10.179 ms6.902 msdirect neighbors 1.47x faster
2M / 10M102.811 ms75.804 msdirect neighbors 1.36x faster

Both adapters assert the same reachable count. The derived TraversalCache closes that gap without changing Topology. An interleaved, allocation-reusing BFS comparison on the same five-outgoing-edge workload measured:

Nodes / edgesLayoutEncoded dual-cache bytesWeavatrix BFSPaired graph_builder BFSResult
200k / 1MFast9.60 MB17.131 ms17.636 ms2.9% faster
200k / 1MBalanced6.10 MB28.104 ms18.197 ms36.5% less memory, slower traversal
200k / 1MCompact4.55 MB76.027 ms18.592 ms52.6% less memory, smallest layout
2M / 10MFast96.00 MB345.978 ms394.968 ms12.4% faster
2M / 10MBalanced68.50 MB464.830 ms322.858 ms28.6% less memory
2M / 10MCompact48.78 MB1,251.840 ms415.216 ms49.2% less memory

The times are medians of nine runs at 1M edges and five runs at 10M, with the measurement order alternated every run. Cache and competitor return the same reachable count; both reuse traversal marks and queue storage. The compressed layouts are explicit space/latency choices, not claims that bit decoding is free. At 20M nodes / 100M edges the measured encoded sizes were 960.00 MB (Fast), 785.00 MB (Balanced), and 536.76 MB (Compact). On adjacency with local ids, Compact can reduce this further through block-local frames while preserving the original order.

On the equal all-pairs output contract, parallel Johnson measured 41.638 ms here versus petgraph’s 64.769 ms, 1.56x faster.

The real-filesystem harness scanned C:\Windows with weavatrix-scan 0.3.0, then built a parent-child containment graph. The scan returned 192,575 files, 240,734 nodes, 240,733 edges, and 51 warnings (complete=false) in 1.904 s. Scanning is outside the graph-build interval:

Real containment graphMedian
Weavatrix auto stable3.469 ms
Weavatrix forced Rayon stable6.782 ms
graph_builder Rayon, narrower contract5.653 ms

The real graph confirms why automatic selection matters: sequential construction is 38.6% faster than the narrower parallel competitor at this size. Reproduce the synthetic and filesystem runs with:

cargo bench --locked --all-features --bench parallel_scale_competitors
cargo bench --locked --all-features --bench traversal_cache_competitors
$env:WEAVATRIX_GRAPH_NODES=20000000
$env:WEAVATRIX_GRAPH_EDGES=100000000
$env:WEAVATRIX_GRAPH_RUNS=3
$env:WEAVATRIX_GRAPH_MODE="fast"
cargo bench --locked --all-features --bench parallel_scale_competitors
$env:WEAVATRIX_REAL_ROOT="C:\Windows"
cargo bench --locked --all-features --bench filesystem_graph_workload

§Advanced algorithms

The A*, dominator, and DAG-intelligence workloads use 10,000 nodes / 30,000 edges. Bellman-Ford uses a 1,000-node / 5,000-edge signed DAG, PageRank uses 500 nodes / 2,000 unique edges and 20 iterations, and DAG reduction/closure uses 512 nodes / 3,000 edges. Values are the median of five independent harness medians:

Algorithmweavatrix-graphpetgraphResult
A*, zero heuristic, cost and path1.130 ms1.495 ms1.32x faster
Bellman-Ford, distances and predecessors0.057 ms0.033 ms1.73x slower
PageRank, 20 iterations0.071 ms12.892 ms181.58x faster
Immediate dominators2.161 ms3.163 ms1.46x faster
Maximum-cost DAG path0.496 ms0.628 ms adapter1.27x faster
Topological generations0.655 ms0.804 ms adapter1.23x faster
Dominance frontiers4.081 ms6.151 ms adapter1.51x faster
DAG transitive reduction and closure0.684 ms1.051 ms1.54x faster

The DAG row includes petgraph’s required conversion to a topologically ordered adjacency list; weavatrix-graph accepts the original graph, validates acyclicity, and returns deterministic node endpoints. The PageRank workload has no parallel edges; our implementation is O(V + E) per iteration and follows the standard teleport plus uniform dangling-mass contract. Its correctness is checked against an independent reference because petgraph 0.8.3 uses a different transition formula.

The Bellman-Ford row is intentionally retained as a known tradeoff, not hidden: our operation snapshots the filtered signed weights once, uses checked i64 addition, distinguishes unreachable nodes without an infinity sentinel, and returns overflow or reachable-negative-cycle errors. petgraph uses f64 distances and does not provide integer overflow semantics. Randomized differential tests cover A* costs, Bellman-Ford distances and negative-cycle status, immediate dominators, longest-path costs, topological generation invariants, dominance-frontier memberships, and exact transitive reduction/closure edges. Petgraph does not expose the three DAG-intelligence operations directly; those rows use equal-output adapters over its graph, topological-sort, and immediate-dominator APIs.

§P0 all-pairs, cuts, and isomorphism

Local Windows release-mode sample from 2026-07-24, with two warmups and the median of 11 measured runs over deterministic synthetic graphs:

ContractWorkloadweavatrix-graphpetgraph
Floyd-Warshall APSP160 nodes / 1,200 weighted edges2.874 ms3.319 ms
Johnson APSP800 nodes / 4,000 weighted edges52.636 ms67.018 ms
Bridges plus articulation points5,000 nodes / 15,000 edges0.362 ms0.302 ms bridges only
Exact directed isomorphism64 nodes / 300 edges0.100 ms0.031 ms

The cuts row is deliberately marked as a different contract rather than a speed win: our traversal returns both cut-edge and cut-vertex evidence. Isomorphism is a known optimization gap. Randomized differential tests compare APSP distances, bridges, articulation points, and exact isomorphism against petgraph 0.8.3. Integer Floyd-Warshall additionally preserves unreachable pairs as None instead of allowing a negative edge to modify an infinity sentinel.

§Biconnected structure and HITS

Biconnected components use 2,000 nodes / 6,000 simple undirected edges. HITS uses 10,000 nodes / 30,000 unique directed relationships, an iteration cap of 100, and tolerance 1e-10. Values are the median of five independent harness medians:

Contractweavatrix-graphReferenceResult
Biconnected edge blocks plus articulation points0.225 msequal-output adapter 0.257 ms1.14x faster
HITS hubs and authorities, L2 normalized7.704 mspetgraph equal-equation adapter 7.950 ms1.03x faster

The direct BCC competitor uses recursive Hopcroft-Tarjan traversal and overflowed the Windows stack on the 10,000 / 30,000 benchmark input. The Weavatrix traversal is iterative; its regression suite includes a 200,000-node chain. Its raw node-block-only lower bound is 0.157 ms, but adding original edge blocks and articulation points raises it to 0.257 ms. The table compares that equal output instead of presenting the narrower operation as equivalent.

Petgraph does not expose HITS directly, so that row uses an equal-equation adapter over its graph storage, including endpoint deduplication, L2 normalization, convergence checks, and the same cap. Seeded dense-matrix references check both score vectors.

§Keyed and stable undirected mutation

The keyed build uses 10,000 domain keys / 30,000 directed edges. Stable undirected construction uses the same size; the churn row removes and reinserts 1,000 edges with cloning/setup outside the timed interval:

Contractweavatrix-graphpetgraphResult
Keyed directed build0.650 msGraphMap 3.788 ms5.83x faster
Stable undirected build0.557 msStableUnGraph 0.230 mspetgraph 2.42x faster
Stable undirected 1,000 remove + 1,000 insert0.169 msStableUnGraph 0.018 mspetgraph 9.39x faster

The keyed row is conservative for Weavatrix: it also stores independent node payloads and returns generation-stable handles. The stable rows document a deliberate safety cost rather than hiding it: Weavatrix detects stale node and edge keys after slot reuse, while petgraph stable indexes can alias a reused slot. Both Weavatrix operations use intrusive incidence and perform no per-node heap allocation.

§Distance analytics and chain decomposition

Distance analytics use 1,500 nodes / 4,500 connected undirected edges. Chain decomposition uses 20,000 nodes / 60,000 simple undirected edges. Values are the median of five independent harness medians; every harness performs two warmups and 11 measured runs:

Equal output contractweavatrix-graphReferenceResult
Eccentricity, radius, diameter, center, and periphery30.890 mspetgraph equal-output adapter 61.343 ms1.99x faster
Chain decomposition5.958 msrustworkx-core 0.18.0 10.797 ms1.81x faster

The distance fast path builds compact neighbor CSR once, then reuses epoch-stamped BFS storage for every source. The petgraph adapter computes the same five outputs, reuses its queue and distance vector, and rejects disconnected graphs under the same contract.

The chain row calls rustworkx-core directly and compares the exact non-bridge endpoint set and chain count. Weavatrix additionally returns original edge IDs and has defined behavior for parallel edges and self-loops; rustworkx documents those inputs as unsupported. Seeded differential tests cover simple graphs, an independent edge-removal reference checks exact non-bridge coverage, and a 200,000-node chain protects the iterative stack-safety contract.

§Edge betweenness and global min-cut

Edge betweenness uses 1,200 nodes / 4,800 simple undirected edges and returns a normalized score for every original edge. Stoer-Wagner uses 350 nodes / 1,400 weighted edges. Values are the median of five independent harness medians; every harness performs two warmups and 11 measured runs:

Equal output contractweavatrix-graphrustworkx-core 0.18.0Result
Edge betweenness, sequential71.367 ms262.602 ms3.68x faster
Edge betweenness, Rayon14.985 ms294.388 ms19.64x faster
Stoer-Wagner global min-cut22.644 ms24.012 ms1.06x faster

Both edge-centrality rows call the rustworkx implementation directly and assert every edge score before timing. The Weavatrix implementation keeps source-local score vectors in the Rayon path and reduces them after traversal; it also preserves parallel-edge identities, gives self-loops a defined zero score, and evaluates semantic filters once per edge.

The min-cut row asserts the same minimum weight. Weavatrix additionally checks negative/non-finite weights and arithmetic overflow, aggregates parallel edges, and returns both sides in deterministic canonical order; rustworkx returns one partition side and uses unchecked weight addition. Reproduce these rows with:

cargo bench --locked --all-features --bench edge_cut_analysis

§P1 matching, coloring, feedback, and Steiner

The workloads use 400 nodes / 1,400 edges for general matching, 180 / 500 for maximal cliques, 5,000 / 15,000 for DSATUR, 10,000 / 30,000 directed edges for feedback arc set, and 1,000 / 4,000 with 32 terminals for Steiner tree:

Equal output contractweavatrix-graphpetgraphResult and quality
Exact maximum matching, materialized pairs0.097 ms0.124 ms1.28x faster; 200 pairs
All maximal cliques0.164 ms0.368 ms2.24x faster; 500 cliques
DSATUR coloring3.299 ms3.550 ms1.08x faster; 5 colors
Eades feedback arc set2.375 ms3.431 ms1.44x faster; 8,216 edges
Multi-start metric-closure Steiner tree5.596 ms965.055 ms172.45x faster; cost 340 vs median 344

The matching adapter consumes petgraph::Matching::edges() into endpoint pairs instead of timing its lazy result. Feedback returns the same set cardinality on the benchmark and no more edges across 24 seeded differential cases. DSATUR uses the same color count across those cases. The deterministic multi-start Steiner result is no more expensive across 20 seeded comparisons and preserves the standard metric-closure two-approximation candidate; the brute-force tests also verify the bound directly on small graphs. Petgraph’s Steiner cost varied from 340 to 344 across the five benchmark processes, while the weavatrix-graph result remained 340.

§P2 bit matrix and optional parallel batches

The bit-matrix workload performs one million deterministic adjacency lookups over 10,000 nodes / 30,000 edges. The batch workloads run 128 BFS traversals and 64 weighted Dijkstra queries over the same dual-CSR topology. Values are the median of five independent harness medians:

Equal output contractSequential / competitorP2 implementationResult
Safe bit-matrix lookuppetgraph FixedBitSet 5.284 msBitMatrix::contains 5.396 mswithin 2.1%
Checked opt-in fast lookuppetgraph FixedBitSet 5.284 mscontains_fast 4.804 ms1.10x faster
Caller-validated lookuppetgraph FixedBitSet 5.284 mscontains_unchecked 3.382 ms1.56x faster
128 BFS traversalssequential 33.258 msRayon 6.609 ms5.03x faster
64 Dijkstra queriessequential 39.771 msRayon 8.699 ms4.57x faster
Johnson APSP, 1,200 / 6,000sequential 217.512 msRayon 64.038 ms3.40x faster
Closeness, 1,000 / 4,000sequential 21.041 msRayon 4.818 ms4.37x faster
Betweenness, 1,000 / 4,000sequential 139.065 msRayon 25.033 ms5.56x faster

BitMatrix uses exactly 12,500,000 payload bytes for the 10,000-square matrix in every mode. The default path is fully safe and essentially at parity. The checked opt-in path beats petgraph while retaining a safe public contract; the caller-validated path is fastest. Unsafe code is feature-gated, isolated, and rejected everywhere else by an architecture test. Rayon is not enabled by default and has no effect on single-query algorithms or no_std builds.

§Lazy traversal, generic costs, and stable mutation

The traversal graph has 50,000 nodes and 150,000 weighted edges. Lazy BFS stops after 128 settlements, generic Dijkstra uses f64, and the mutation workload builds the same graph before removing and replacing 100 nodes. Values are the median of five independent harness medians:

Equal output contractweavatrix-graphpetgraphResult
Lazy BFS, first 128 nodes0.002 ms0.003 ms1.50x faster
Generic f64 Dijkstra to target8.342 ms11.936 ms1.43x faster
Stable build/remove/reinsert2.247 ms2.227 mswithin 0.9%

The mutable row is conservative: StablePayloadGraph also detects stale keys after slot reuse through a generation counter. Its adjacency is an intrusive slot list, so construction performs no per-node adjacency allocations. Filtered views are genuinely lazy: creating an adjacency iterator does not evaluate its predicate, and early stopping evaluates only the consumed prefix.

§Filtered components and condensation

10,000 nodes and 30,000 edges. Each measured sample batches 64 operations; the table is the median of five independent harness medians:

Equal output contractweavatrix-graphpetgraph
Filtered SCC memberships0.899 ms1.353 ms
Filtered topological order0.080 ms0.427 ms
Weak component memberships0.206 ms0.208 ms
Condensation DAG and memberships0.821 ms2.385 ms

The petgraph filtered rows use EdgeFiltered rather than rebuilding a graph. Both weak-component rows return complete deterministic memberships, not only a component count. Condensation consumes the petgraph input, so input clones are prepared outside the timed interval. Randomized differential tests compare exact SCC and weak-component partitions plus canonical condensation edges.

Incoming and outgoing indexes are rebuilt during graph construction and deserialization. They are intentionally excluded from JSON, so the canonical wire format remains only nodes and edges. Resolve a stable string id once with node_index, then use node_at, outgoing_at, incoming_at, out_degree, and in_degree in repeated graph algorithms.

Extractors that already emit sorted nodes can use Graph::try_from_sorted_nodes; fully canonical input can use Graph::try_from_sorted_parts. Both keep validation, endpoint checks, deduplication, and both indexes. Unordered input safely falls back to the canonicalizing constructor.

petgraph, graaf, graph_builder, rustworkx-core, and weavatrix-scan are dev-dependencies only. The default runtime dependency budget remains serde; Rayon and its transitive dependencies appear only when the rayon feature is explicitly selected.

Timing varies by allocator, CPU, and build toolchain. Run the included harnesses on the deployment target before using these figures for capacity planning.

§Quality Gates

Local checks:

cargo fmt --check
cargo test --all-features --locked
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo check --no-default-features --target thumbv7em-none-eabihf --lib --locked
cargo check --no-default-features --features unsafe-fast --target thumbv7em-none-eabihf --lib --locked
cargo doc --locked --no-deps --all-features
cargo llvm-cov --workspace --all-features --fail-under-lines 85
cargo bench --all-features --locked

The release gates combine the test suite with strict architecture verification: every Rust source stays at or below 300 lines, every function stays at or below 100 lines, module source forms cannot collide, domain facades remain focused, runtime dependencies remain limited, and canonical kind strings cannot collide. Production source contains no .unwrap() or .expect() calls: internal graph invariants use checked conversions, fallible propagation, or total control flow instead of process-terminating shortcuts.

CI also runs measured Rust coverage with cargo-llvm-cov, emits lcov.info for analyzer import, and fails below 85% line coverage. It additionally runs Linux proptest contracts, Miri over traversal/view/analytics/mutable storage, and bounded libFuzzer smoke targets for topology, matrices, mutation, and interchange formats. Weavatrix architecture verification is backed by the strict .weavatrix/architecture.json contract. The current local MSVC LLVM report measures 92.28% of lines and 88.81% of functions.

§License

MIT

Structs§

AcyclicPayloadGraph
A stable mutable payload graph that rejects cycle-creating mutations.
AllPairsShortestPaths
AutoAllPairs
BellmanFord
Bfs
Lazy breadth-first traversal backed by reusable allocation storage.
BiconnectedComponents
Deterministic vertex-biconnected edge blocks and their cut vertices.
BipartiteMatching
BipartitePartition
BitMatrix
CacheBfs
Lazy cache-backed breadth-first traversal.
CacheDfs
Lazy cache-backed depth-first traversal.
ChainDecomposition
Deterministic edge-disjoint chains of an undirected DFS forest.
ChainStep
One oriented edge in a DFS chain.
CliqueEnumeration
Coloring
Communities
Condensation
CycleEnumeration
DagTransitive
DenseMatrix
Dfs
Lazy depth-first traversal backed by reusable allocation storage.
DfsEventWorkspace
Reusable color map and iterative stack for DFS event traversal.
Dijkstra
Lazy Dijkstra settlement order with reusable allocation storage.
DijkstraWorkspace
Reusable distances, predecessors, node slots, and priority queue.
DistanceAnalytics
Exact unweighted distance metrics for a connected undirected graph.
DominanceFrontiers
Dominators
DominatorsIter
Edge
EdgeEndpoints
EdgeFilter
EdgeFiltered
EdgeIndex
FeedbackArcSet
FiniteF64
Deterministic JSON-like attribute value for graph extensions.
FreezeMap
FrozenGraph
FrozenPayloadGraph
FrozenUndirectedPayloadGraph
Graph
GraphBuilder
Hits
HITS hub and authority scores in canonical node order.
IsomorphismSearch
IterativeCentrality
KeyedPayloadGraph
A GraphMap-style key index backed by generation-stable graph handles.
LegacyGraph
Compatibility representation for the current JavaScript Weavatrix graph.
LegacyLink
Legacy link shape with all unknown fields preserved as attributes.
LegacyNode
Legacy node shape with all unknown fields preserved as attributes.
LegacyPoint
LegacyRange
MaxFlow
MaximumMatching
MinCostFlow
NeighborIter
Exact-size lazy iterator over direct neighbor node indexes.
Node
NodeFiltered
NodeId
NodeIndex
PathEnumeration
PayloadFreezeMap
PayloadGraph
Provenance
RandomGraphGenerator
Reversed
SignedPath
SourcePosition
SourceSpan
SpanningForest
StableEdgeKey
StableNodeKey
StablePayloadGraph
A mutable directed payload graph with generation-checked stable keys.
StableUndirectedPayloadGraph
A mutable undirected payload graph with generation-checked stable keys.
SteinerTree
StoerWagnerCut
A deterministic global minimum cut and both sides of its partition.
Topology
TopologyProjection
TraversalCache
TraversalCacheWorkspace
Reusable allocation storage for cache-backed BFS and DFS.
TraversalWorkspace
Reusable allocation storage for breadth-first and depth-first traversals.
UndirectedCuts
UndirectedPayloadGraph
UndirectedTopology
WeightedPath
WorkingGraph

Enums§

AllPairsStrategy
AttributeValue
Deterministic JSON-like attribute value for graph extensions.
Confidence
DfsEvent
Direction
EdgeKind
Semantic relationship between two graph nodes.
EvidenceKind
Origin of the evidence supporting an edge.
GraphError
GraphMlTopology
NodeKind
Semantic role of a graph node.
SubgraphMode
TraversalControl
TraversalLayout
Actual physical layout selected for a traversal cache.
TraversalStorage
Chooses the speed/space trade-off of a derived traversal cache.

Traits§

GraphView
IndexGraphView
IndexUndirectedGraphView
Measure
Ordered path cost with checked addition.
UndirectedGraphView

Functions§

all_pairs_auto
Selects Floyd-Warshall for small/dense graphs and Johnson for sparse graphs.
all_pairs_auto_filtered
Automatically selects an all-pairs algorithm over a filtered edge set.
all_simple_paths
astar
astar_filtered
bellman_ford
Computes signed shortest paths from source.
bellman_ford_filtered
Computes signed shortest paths using only edges with a returned cost.
bellman_ford_measure
Computes shortest paths with an arbitrary signed or unsigned measure.
bellman_ford_measure_filtered
Computes filtered shortest paths with an arbitrary checked measure.
betweenness_centrality
bfs
bfs_filtered
bfs_iter
bfs_iter_filtered
biconnected_components
Finds vertex-biconnected edge blocks and articulation points.
biconnected_components_filtered
Finds vertex-biconnected edge blocks using accepted edges only.
bidirectional_dijkstra
bipartite_partition
bridges_and_articulation_points
center
Returns all center nodes of a connected graph.
chain_decomposition
Computes a chain decomposition of every connected component in O(V + E).
chain_decomposition_filtered
Computes chains using accepted edges only.
chain_decomposition_from
Computes chains only in the connected component containing source.
chain_decomposition_from_filtered
Computes accepted-edge chains in the component containing source.
closeness_centrality
complement
Materializes the directed simple-graph complement.
complete_bipartite_topology
Generates all directed edges from the left partition to the right.
complete_topology
Generates all directed edges between distinct nodes.
condensation
Builds the acyclic graph of strongly connected components.
condensation_filtered
Builds a condensation DAG using only edges accepted by allows_edge.
cycle_basis
Returns a deterministic fundamental cycle basis of the undirected projection.
cycle_topology
Generates one directed cycle, including a self-loop for one node.
dag_longest_path
Returns a deterministic longest path in a directed acyclic graph.
dag_longest_path_filtered
Returns a deterministic longest path over accepted DAG edges.
dag_longest_path_length
Returns the number of edges in a deterministic longest DAG path.
dag_longest_path_length_filtered
Returns the number of accepted edges in a deterministic longest DAG path.
dag_transitive_reduction_closure
Computes a DAG’s unique transitive reduction and transitive closure.
dag_transitive_reduction_closure_filtered
Computes transitive reduction and closure over selected edges.
dag_weighted_longest_path
Returns a deterministic maximum-cost path in a directed acyclic graph.
dag_weighted_longest_path_length
Returns only the maximum path cost.
degree_centrality
depth_first_search
depth_first_search_filtered
dfs
dfs_filtered
dfs_iter
dfs_iter_filtered
diameter
Returns the exact diameter of a connected graph.
dijkstra
dijkstra_filtered
dijkstra_iter
dijkstra_iter_filtered
dijkstra_measure
Computes a shortest path with an arbitrary checked measure.
dijkstra_measure_filtered
Computes a filtered shortest path with an arbitrary checked measure.
distance_analytics
Computes exact unweighted distance metrics.
distance_analytics_filtered
Computes exact metrics using accepted edges only.
dominance_frontiers
dominance_frontiers_filtered
dominators
dominators_filtered
dsatur_coloring
Produces a deterministic DSATUR coloring.
eccentricity
Returns the exact eccentricity of node in a connected graph.
edge_betweenness_centrality
Computes unweighted Brandes edge betweenness for a directed graph view.
edge_betweenness_centrality_filtered
Filtered edge betweenness. The predicate is evaluated once per edge.
edge_filtered
edmonds_karp
Computes maximum flow with the Edmonds-Karp shortest augmenting-path rule.
eigenvector_centrality
Computes eigenvector centrality by shifted power iteration.
feedback_arc_set_heuristic
Approximates a directed feedback arc set with the Eades ordering heuristic.
find_cycle
find_cycle_filtered
floyd_warshall
Computes all-pairs signed shortest paths with Floyd-Warshall.
floyd_warshall_filtered
Computes Floyd-Warshall while omitting edges whose cost is None.
graph6_decode
Decodes one Graph6 record into a compact undirected topology.
graph6_encode
Encodes a compact simple undirected graph in Graph6 form.
graph_isomorphic
graphml_decode
Imports the structural GraphML subset: one graph, nodes, and edges.
grid_topology
Generates a directed rectangular grid with rightward and downward edges.
has_cycle
has_cycle_filtered
hits
Computes HITS hub and authority scores on topological relationships.
hits_filtered
Computes HITS scores using accepted relationships only.
induced_subgraph_view
johnson_all_pairs
Computes sparse all-pairs signed shortest paths with Johnson’s algorithm.
johnson_all_pairs_filtered
Computes Johnson all-pairs paths while omitting edges whose cost is None.
johnson_cycles
Enumerates elementary directed circuits with Johnson’s blocked-set algorithm.
k_core_numbers
k_shortest_paths
katz_centrality
Computes Katz centrality by fixed-point iteration.
label_propagation_communities
Deterministic asynchronous label propagation over the undirected projection.
maximal_cliques
maximum_bipartite_matching
maximum_flow
Computes a directed maximum flow with Dinic’s blocking-flow algorithm.
maximum_matching
Computes a maximum-cardinality matching in a general undirected graph.
min_cost_max_flow
Computes a maximum flow of minimum cost with successive shortest paths.
minimum_spanning_forest
page_rank
Computes PageRank in graph node order.
page_rank_filtered
Computes PageRank over the selected edges in graph node order.
path_topology
Generates 0 -> 1 -> ... -> n-1.
periphery
Returns all peripheral nodes of a connected graph.
prim_spanning_forest
push_relabel
Computes maximum flow with a deterministic FIFO push-relabel algorithm.
radius
Returns the exact radius of a connected graph.
reachable
reachable_filtered
reversed
shortest_path
shortest_path_filtered
spfa
Computes signed single-source paths with the queue-based SPFA algorithm.
spfa_filtered
Computes SPFA while omitting edges whose cost is None.
star_topology
Generates a directed star with node zero as its center.
steiner_tree_approximation
Builds a deterministic metric-closure Steiner-tree approximation.
stoer_wagner_min_cut
Finds the global minimum cut of an undirected weighted multigraph.
stoer_wagner_min_cut_filtered
Filtered Stoer-Wagner min-cut. Each predicate and accepted weight callback is evaluated exactly once per edge.
strongly_connected_components
strongly_connected_components_filtered
subgraph_isomorphisms
topological_generations
topological_generations_filtered
topological_sort
topological_sort_filtered
topology_from_dot
Imports the numeric strict-DOT subset emitted by topology_to_dot.
topology_to_dot
Exports a directed numeric topology as deterministic strict DOT.
topology_to_graphml
Exports a directed numeric topology as deterministic GraphML.
undirected_edge_betweenness_centrality
Computes unweighted Brandes edge betweenness for an undirected graph view.
undirected_edge_betweenness_centrality_filtered
Filtered undirected edge betweenness. The predicate runs once per edge.
undirected_from_dot
Imports the numeric strict-DOT subset emitted by undirected_to_dot.
undirected_to_dot
Exports an undirected numeric topology as deterministic strict DOT.
undirected_to_graphml
Exports an undirected numeric topology as deterministic GraphML.
union
Materializes the simple union of two graphs by node identity.
weakly_connected_components
weakly_connected_components_filtered

Type Aliases§

GraphNodeIndex
Backward-compatible name for a compact topology node index.
HitsScores
Canonically ordered node-score pairs returned by HITS.
Result