graph_api_benches/index/edge_label/
mod.rs

1use criterion::{BenchmarkGroup, measurement::WallTime};
2use graph_api_derive::{EdgeExt, VertexExt};
3use graph_api_lib::Graph;
4
5use std::fmt::Debug;
6use uuid::Uuid;
7
8// Define a model with edge label indexes
9#[derive(Debug, Clone, VertexExt)]
10pub enum Vertex {
11    Person {
12        name: String,
13        age: u64,
14        unique_id: Uuid,
15        username: String,
16        biography: String,
17    },
18    Project {
19        name: String,
20    },
21    Rust,
22}
23
24#[derive(Debug, Clone, EdgeExt)]
25pub enum Edge {
26    Knows { since: i32 },
27    Created,
28    Language { name: String },
29}
30
31// Generate test data with the EdgeLabelVertex and EdgeLabelEdge models
32pub fn populate_test_data<G>(graph: &mut G) -> (Vec<G::VertexId>, Vec<G::EdgeId>)
33where
34    G: Graph<Vertex = Vertex, Edge = Edge>,
35{
36    let mut person_ids = vec![];
37    let mut edge_ids = vec![];
38
39    // Create person vertices
40    for i in 0..20 {
41        let id = graph.add_vertex(Vertex::Person {
42            name: format!("Person{}", i),
43            age: 25 + (i % 50) as u64,
44            unique_id: Uuid::new_v4(),
45            username: format!("user{}", i),
46            biography: format!("Bio for person {}", i),
47        });
48        person_ids.push(id);
49    }
50
51    // Create edges of different types
52    for i in 0..19 {
53        // Create "knows" edges
54        if i % 3 == 0 {
55            let edge_id = graph.add_edge(
56                person_ids[i],
57                person_ids[i + 1],
58                Edge::Knows {
59                    since: 2020 + (i as i32),
60                },
61            );
62            edge_ids.push(edge_id);
63        }
64    }
65
66    // Add a project and created edges
67    let project = graph.add_vertex(Vertex::Project {
68        name: "TestProject".to_string(),
69    });
70
71    for id in person_ids.iter().take(5) {
72        let edge_id = graph.add_edge(*id, project, Edge::Created);
73        edge_ids.push(edge_id);
74    }
75
76    // Add rust and language edges
77    let rust = graph.add_vertex(Vertex::Rust);
78
79    let edge_id = graph.add_edge(
80        project,
81        rust,
82        Edge::Language {
83            name: "Rust".to_string(),
84        },
85    );
86    edge_ids.push(edge_id);
87
88    (person_ids, edge_ids)
89}
90
91#[cfg(feature = "edge-label-index")]
92pub fn run_benchmarks<G>(group: &mut BenchmarkGroup<WallTime>, setup: impl Fn() -> G + Clone)
93where
94    G: Graph<Vertex = Vertex, Edge = Edge> + graph_api_lib::SupportsEdgeLabelIndex,
95{
96    // Benchmark edge label index lookup for "knows" edges
97    group.throughput(criterion::Throughput::Elements(1));
98    group.bench_function("edge_label_knows_lookup", |b| {
99        // Setup: Create graph with test data
100        let mut graph = setup();
101        populate_test_data(&mut graph);
102
103        b.iter(|| {
104            // Query edges with "knows" label
105            let results = graph
106                .walk()
107                .vertices(graph_api_lib::VertexSearch::scan())
108                .take(5)
109                .edges(Edge::knows())
110                .collect::<Vec<_>>();
111
112            results
113        })
114    });
115
116    // Benchmark edge label index lookup for "created" edges
117    group.bench_function("edge_label_created_lookup", |b| {
118        // Setup: Create graph with test data
119        let mut graph = setup();
120        populate_test_data(&mut graph);
121
122        b.iter(|| {
123            // Query edges with "created" label
124            let results = graph
125                .walk()
126                .vertices(graph_api_lib::VertexSearch::scan())
127                .take(10)
128                .edges(Edge::created())
129                .collect::<Vec<_>>();
130
131            results
132        })
133    });
134
135    // Benchmark insertion with edge label index
136    group.bench_function("edge_label_insertion", |b| {
137        // Setup: Create graph with minimal data for adding edges
138        let mut graph = setup();
139        let (person_ids, _) = populate_test_data(&mut graph);
140        let src = person_ids[0];
141        let dst = person_ids[1];
142
143        b.iter(|| graph.add_edge(src, dst, Edge::Knows { since: 2023 }))
144    });
145
146    // Benchmark removal with edge label index
147    group.bench_function("edge_label_removal", |b| {
148        // Setup: Create a new graph with an edge for each iteration
149        b.iter_with_setup(
150            || {
151                let mut graph = setup();
152                let (person_ids, _) = populate_test_data(&mut graph);
153                let edge_id =
154                    graph.add_edge(person_ids[0], person_ids[1], Edge::Knows { since: 2020 });
155                (graph, edge_id)
156            },
157            |(mut graph, edge_id)| {
158                graph.remove_edge(edge_id);
159            },
160        )
161    });
162}
163
164#[cfg(not(feature = "edge-label-index"))]
165pub fn run_benchmarks<G>(_group: &mut BenchmarkGroup<WallTime>, _setup: impl Fn() -> G + Clone)
166where
167    G: Graph<Vertex = Vertex, Edge = Edge>,
168{
169    // No-op when feature is disabled
170}