A fast, lightweight and extensible implementation of a graph data structure.
Lightweight & fast.
By default, SlotMaps are used to store the nodes and edges which solves the ABA problem while also providing O(1) insertion, deletion and lookup times. Additionally, and optionally,
HashBrown is used instead of std::HashMap to map category names to ids in the [CategoryGraph] struct.
Extensible & Generic
The [Graph] is generic over the node and edge data types, which can be any type that implements [Clone]. There's also traits for making even more customized graph-like data structures if the need arises.
Serde & Specta
There's optional features to enable [serde] & [specta] support.
Categories
The [CategoryGraph] struct uses a hash map to map category names ([String]) to a category node ([NodeID]) (where the node's edges are the nodes belonging to the category). There's also some useful extra functions to query categories and their nodes, and a [Categorized] trait that can be implemented for a custom struct if needed.
In other words a simple extension to the graph that allows for efficient and easy grouping of nodes by strings.
Structure
[Node] - Struct representing a node in the graph. Contains a [NodeID] which is a key to the node in the slotmap, which has a generic data field and a list of edges.
[Edge] - Struct representing an edge in the graph. Contains an [EdgeID] which is a key to the edge in the slotmap, and two [NodeID]s which are the nodes the edge connects (from & to). An edge can also have "data", which could be anything or nothing; for example the weight of the connection or a struct or enum representing something else.
[GraphWriter] - Trait defining methods to alter a graph, i.e. adding, removing, and editing nodes and edges.
[SlotMapGraph] - Trait defining methods to access the nodes and edges of a graph where the nodes and edges are stored in slotmaps. Implements [GraphWriter].
[Graph] - The default graph struct which implements [SlotMapGraph]. It only contains two slotmaps, one for nodes and one for edges.
[Categorized] - Trait that extends [SlotMapGraph] with category specific methods.
[CategoryGraph] - A graph with categories. Categories are normal nodes (which can contain edges & data), but the graph also contains a hashmap that maps category names to category nodes for easy access.
Examples
Simple [Graph] and the ABA problem.
use ;
/* We need to have these traits in scope: */
use ;
;
;
let mut graph: = new;
let node1 = graph.add_node.clone;
let node2 = graph.add_node.clone;
let edge1 = graph.add_edge.clone;
assert_eq!;
assert_eq!;
graph.remove_node.unwrap;
// Since we just removed node 1, it should be None now.
assert_eq!;
// And node 2 still points to node 2.
assert_eq!;
println!;
[CategoryGraph] example
use *;
let mut graph: = new;
let node1 = graph.add_node.id;
let node2 = graph.add_node.id;
let node3 = graph.add_node.id;
let category1 = graph.create_category.unwrap;
assert_eq!;
// The category node should have the same data as the one we passed in.
let category1_data = graph.category.unwrap.data.clone;
if let CategoryData = category1_data
// Adding to a category that doesn't exist will create it.
let category2 = graph.add_to_category;
assert_eq!;
// Adding to the same category twice will return the same category node.
let category2_1 = graph.add_to_category;
assert_eq!;
assert_eq!;
// The "Category 2" node should have two connections, one to node2 and one to node3.
let category2_node = graph.category.unwrap;
assert_eq!;
// Creating a category twice will error.
assert!;