graph_api_simplegraph/graph/
mod.rs

1mod debug;
2mod iter;
3mod label;
4
5use crate::EdgeId;
6use crate::graph::iter::RangeOrNoneIterator;
7use crate::graph::label::{Adjacency, LabelledEdges, LabelledVertices, VertexStorage};
8use crate::id::VertexId;
9use crate::index::VertexIndexStorage;
10use graph_api_lib::{
11    Direction, EdgeSearch, Element, ElementId, Graph, Index, Label, Project, ProjectMut,
12    SupportsClear, SupportsEdgeAdjacentLabelIndex, SupportsEdgeHashIndex, SupportsEdgeLabelIndex,
13    SupportsEdgeRangeIndex, SupportsVertexFullTextIndex, SupportsVertexHashIndex,
14    SupportsVertexLabelIndex, SupportsVertexRangeIndex, Value, VertexSearch,
15};
16use smallbox::space::S8;
17use smallbox::{SmallBox, smallbox};
18use std::fmt::{Debug, Formatter};
19use std::marker::PhantomData;
20
21/// A graph that is backed by a simple in-memory data structure.
22pub struct SimpleGraph<Vertex, Edge>
23where
24    Vertex: Element,
25    Edge: Element,
26{
27    /// The list of labels. We know this number up-front. So this is a regular vec.
28    vertices: Vec<LabelledVertices<Vertex, Edge>>,
29    indexes: Vec<VertexIndexStorage>,
30    edges: Vec<LabelledEdges<Edge>>,
31}
32
33#[derive(Debug)]
34pub struct VertexReference<'graph, Graph>
35where
36    Graph: graph_api_lib::Graph,
37{
38    id: Graph::VertexId,
39    weight: &'graph Graph::Vertex,
40}
41
42impl<Graph> From<VertexReference<'_, Graph>> for ElementId<Graph>
43where
44    Graph: graph_api_lib::Graph,
45{
46    fn from(value: VertexReference<Graph>) -> Self {
47        ElementId::Vertex(value.id)
48    }
49}
50
51impl<'graph, Graph> graph_api_lib::VertexReference<'graph, Graph> for VertexReference<'graph, Graph>
52where
53    Graph: graph_api_lib::Graph,
54{
55    fn id(&self) -> Graph::VertexId {
56        self.id
57    }
58
59    fn weight(&self) -> &Graph::Vertex {
60        self.weight
61    }
62
63    fn project<
64        'reference,
65        T: graph_api_lib::Project<'reference, <Graph as graph_api_lib::Graph>::Vertex>,
66    >(
67        &'reference self,
68    ) -> Option<T> {
69        graph_api_lib::Project::project(self.weight)
70    }
71}
72
73pub struct VertexReferenceMut<'graph, Graph>
74where
75    Graph: graph_api_lib::Graph,
76{
77    indexes: &'graph mut Vec<VertexIndexStorage>,
78    id: Graph::VertexId,
79    weight: &'graph mut Graph::Vertex,
80}
81
82impl<Graph> Debug for VertexReferenceMut<'_, Graph>
83where
84    Graph: graph_api_lib::Graph,
85{
86    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87        f.debug_struct("VertexReferenceMut")
88            .field("id", &self.id)
89            .field("weight", &self.weight)
90            .finish()
91    }
92}
93
94impl<Graph> From<VertexReferenceMut<'_, Graph>> for ElementId<Graph>
95where
96    Graph: graph_api_lib::Graph,
97{
98    fn from(value: VertexReferenceMut<Graph>) -> Self {
99        ElementId::Vertex(value.id)
100    }
101}
102
103impl<'graph, Graph> graph_api_lib::VertexReference<'graph, Graph>
104    for VertexReferenceMut<'graph, Graph>
105where
106    Graph: graph_api_lib::Graph,
107{
108    fn id(&self) -> Graph::VertexId {
109        self.id
110    }
111
112    fn weight(&self) -> &Graph::Vertex {
113        self.weight
114    }
115
116    fn project<
117        'reference,
118        T: graph_api_lib::Project<'reference, <Graph as graph_api_lib::Graph>::Vertex>,
119    >(
120        &'reference self,
121    ) -> Option<T> {
122        graph_api_lib::Project::project(self.weight)
123    }
124}
125
126impl<'graph, Graph> graph_api_lib::VertexReferenceMut<'graph, Graph>
127    for VertexReferenceMut<'graph, Graph>
128where
129    Graph: graph_api_lib::Graph<VertexId = VertexId> + 'graph,
130{
131    type MutationListener<'reference> = VertexMutationListener<'reference, Graph::Vertex>;
132
133    fn weight_mut(&mut self) -> &mut Graph::Vertex {
134        self.weight
135    }
136
137    fn project_mut<
138        'reference,
139        T: graph_api_lib::ProjectMut<
140                'reference,
141                <Graph as graph_api_lib::Graph>::Vertex,
142                Self::MutationListener<'reference>,
143            >,
144    >(
145        &'reference mut self,
146    ) -> Option<T> {
147        graph_api_lib::ProjectMut::project_mut(
148            self.weight,
149            VertexMutationListener {
150                phantom_data: Default::default(),
151                indexes: self.indexes,
152                id: self.id.vertex(),
153            },
154        )
155    }
156}
157
158pub struct VertexMutationListener<'reference, Element> {
159    phantom_data: PhantomData<Element>,
160    indexes: &'reference mut Vec<VertexIndexStorage>,
161    id: u32,
162}
163
164impl<'reference, Element> graph_api_lib::MutationListener<'reference, Element>
165    for VertexMutationListener<'reference, Element>
166where
167    Element: graph_api_lib::Element,
168{
169    fn update(&mut self, index: <Element::Label as Label>::Index, before: Value, after: Value) {
170        let actual_index = &mut self.indexes[index.ordinal()];
171        actual_index.remove(&before, self.id, &index);
172        actual_index.insert(after, self.id, &index);
173    }
174}
175
176#[derive(Debug)]
177pub struct EdgeReference<'a, Graph>
178where
179    Graph: graph_api_lib::Graph,
180{
181    id: EdgeId,
182    weight: &'a Graph::Edge,
183}
184
185impl<Graph> From<EdgeReference<'_, Graph>> for ElementId<Graph>
186where
187    Graph: graph_api_lib::Graph<VertexId = VertexId, EdgeId = EdgeId>,
188{
189    fn from(value: EdgeReference<Graph>) -> ElementId<Graph> {
190        ElementId::Edge(value.id)
191    }
192}
193
194impl<'a, Graph> graph_api_lib::EdgeReference<'a, Graph> for EdgeReference<'a, Graph>
195where
196    Graph: graph_api_lib::Graph<VertexId = VertexId, EdgeId = EdgeId>,
197{
198    fn id(&self) -> Graph::EdgeId {
199        self.id
200    }
201
202    fn tail(&self) -> Graph::VertexId {
203        self.id.tail()
204    }
205
206    fn head(&self) -> Graph::VertexId {
207        self.id.head()
208    }
209
210    fn weight(&self) -> &Graph::Edge {
211        self.weight
212    }
213
214    fn project<'reference, T: Project<'reference, <Graph as graph_api_lib::Graph>::Edge>>(
215        &'reference self,
216    ) -> Option<T> {
217        graph_api_lib::Project::project(self.weight)
218    }
219}
220
221#[derive(Debug)]
222pub struct EdgeReferenceMut<'a, Graph>
223where
224    Graph: graph_api_lib::Graph,
225{
226    id: Graph::EdgeId,
227    tail: Graph::VertexId,
228    head: Graph::VertexId,
229    weight: &'a mut Graph::Edge,
230}
231
232impl<Graph> From<EdgeReferenceMut<'_, Graph>> for ElementId<Graph>
233where
234    Graph: graph_api_lib::Graph,
235{
236    fn from(value: EdgeReferenceMut<Graph>) -> Self {
237        ElementId::Edge(value.id)
238    }
239}
240
241impl<Graph> graph_api_lib::EdgeReference<'_, Graph> for EdgeReferenceMut<'_, Graph>
242where
243    Graph: graph_api_lib::Graph,
244{
245    fn id(&self) -> Graph::EdgeId {
246        self.id
247    }
248
249    fn tail(&self) -> Graph::VertexId {
250        self.tail
251    }
252
253    fn head(&self) -> Graph::VertexId {
254        self.head
255    }
256
257    fn weight(&self) -> &Graph::Edge {
258        self.weight
259    }
260
261    fn project<'reference, T: Project<'reference, <Graph as graph_api_lib::Graph>::Edge>>(
262        &'reference self,
263    ) -> Option<T> {
264        graph_api_lib::Project::project(self.weight)
265    }
266}
267
268impl<Graph> graph_api_lib::EdgeReferenceMut<'_, Graph> for EdgeReferenceMut<'_, Graph>
269where
270    Graph: graph_api_lib::Graph,
271{
272    type MutationListener<'reference> = ();
273
274    fn weight_mut(&mut self) -> &mut Graph::Edge {
275        self.weight
276    }
277
278    fn project_mut<
279        'reference,
280        T: ProjectMut<
281                'reference,
282                <Graph as graph_api_lib::Graph>::Edge,
283                Self::MutationListener<'reference>,
284            >,
285    >(
286        &'reference mut self,
287    ) -> Option<T> {
288        graph_api_lib::ProjectMut::project_mut(self.weight, ())
289    }
290}
291
292pub struct VertexIter<'search, 'graph, Graph>
293where
294    Graph: graph_api_lib::Graph + 'graph,
295{
296    _phantom: PhantomData<&'search ()>,
297    vertices: &'graph [LabelledVertices<Graph::Vertex, Graph::Edge>], // All vertex groups
298    iter: SmallBox<dyn Iterator<Item = VertexId> + 'graph, S8>, // Indexed iterator over vertices in the current group
299    count: usize,
300    limit: usize,
301}
302
303impl<'graph, Graph> Iterator for VertexIter<'_, 'graph, Graph>
304where
305    Graph: graph_api_lib::Graph<VertexId = VertexId> + 'graph,
306{
307    type Item = VertexReference<'graph, Graph>;
308
309    fn next(&mut self) -> Option<Self::Item> {
310        if self.count >= self.limit {
311            return None;
312        }
313        if let Some(id) = self.iter.next() {
314            self.count += 1;
315            return Some(VertexReference {
316                weight: &self.vertices[id.label() as usize][id.vertex()].weight,
317                id,
318            });
319        }
320        None
321    }
322}
323
324type RangeIter = dyn Iterator<Item = (Option<Direction>, Option<u16>, Option<u16>)>;
325type BoxedRangeIter = SmallBox<RangeIter, S8>;
326
327// The edge iterator lazily creates ranges when iterating over the adjacency list
328pub struct EdgeIter<'search, 'graph, Graph>
329where
330    Graph: graph_api_lib::Graph,
331{
332    _phantom: PhantomData<&'search ()>,
333    vertex: VertexId,
334    vertex_storage: &'graph VertexStorage<Graph::Vertex>,
335    edges: &'graph [LabelledEdges<Graph::Edge>],
336    range_iter: BoxedRangeIter,
337    current_iter: Option<std::collections::btree_set::Range<'graph, Adjacency>>,
338    count: usize,
339    limit: usize,
340}
341
342impl<'graph, Graph> Iterator for EdgeIter<'_, 'graph, Graph>
343where
344    Graph: graph_api_lib::Graph<VertexId = crate::id::VertexId> + 'graph,
345{
346    type Item = EdgeReference<'graph, Graph>;
347
348    fn next(&mut self) -> Option<Self::Item> {
349        if self.count >= self.limit {
350            return None;
351        }
352        loop {
353            if self.current_iter.is_none() {
354                if let Some((direction, label, adjacent_label)) = self.range_iter.next() {
355                    self.current_iter =
356                        Some(self.vertex_storage.adjacency_list.range(Adjacency::range(
357                            direction,
358                            label,
359                            adjacent_label,
360                        )));
361                } else {
362                    return None;
363                }
364            }
365            if let Some(iter) = &mut self.current_iter {
366                if let Some(adjacency) = iter.next() {
367                    self.count += 1;
368                    match adjacency.direction {
369                        Direction::Outgoing => {
370                            return Some(EdgeReference {
371                                id: EdgeId::new(
372                                    adjacency.edge_label,
373                                    adjacency.edge_id,
374                                    self.vertex,
375                                    VertexId::new(adjacency.vertex_label, adjacency.vertex_id),
376                                ),
377                                weight: &self.edges[adjacency.edge_label as usize].edges
378                                    [adjacency.edge_id as usize],
379                            });
380                        }
381                        Direction::Incoming => {
382                            return Some(EdgeReference {
383                                id: EdgeId::new(
384                                    adjacency.edge_label,
385                                    adjacency.edge_id,
386                                    VertexId::new(adjacency.vertex_label, adjacency.vertex_id),
387                                    self.vertex,
388                                ),
389                                weight: &self.edges[adjacency.edge_label as usize].edges
390                                    [adjacency.edge_id as usize],
391                            });
392                        }
393                        _ => {
394                            unreachable!()
395                        }
396                    };
397                }
398            }
399            self.current_iter = None;
400        }
401    }
402}
403
404impl<Vertex, Edge> Default for SimpleGraph<Vertex, Edge>
405where
406    Vertex: Element,
407    Edge: Element,
408{
409    fn default() -> Self {
410        Self::new()
411    }
412}
413
414impl<Vertex, Edge> SimpleGraph<Vertex, Edge>
415where
416    Vertex: Element,
417    Edge: Element,
418{
419    pub fn new() -> Self {
420        Self {
421            vertices: (0..Vertex::Label::variants().len())
422                .map(|_i| LabelledVertices::new())
423                .collect(),
424            indexes: <Vertex::Label as Label>::variants()
425                .iter()
426                .flat_map(|label| label.indexes().iter())
427                .map(|i| i.into())
428                .collect(),
429            edges: (0..Edge::Label::variants().len())
430                .map(|_i| LabelledEdges::new())
431                .collect(),
432        }
433    }
434}
435
436impl<Vertex, Edge> Graph for SimpleGraph<Vertex, Edge>
437where
438    Vertex: Element,
439    Edge: Element,
440{
441    type Vertex = Vertex;
442    type Edge = Edge;
443    type VertexId = VertexId;
444    type EdgeId = EdgeId;
445    type VertexReference<'graph>
446        = VertexReference<'graph, Self>
447    where
448        Self: 'graph;
449    type VertexReferenceMut<'graph>
450        = VertexReferenceMut<'graph, Self>
451    where
452        Self: 'graph;
453    type EdgeReference<'graph>
454        = EdgeReference<'graph, Self>
455    where
456        Self: 'graph;
457    type EdgeReferenceMut<'graph>
458        = EdgeReferenceMut<'graph, Self>
459    where
460        Self: 'graph;
461    type EdgeIter<'search, 'graph>
462        = EdgeIter<'search, 'graph, Self>
463    where
464        Self: 'graph;
465    type VertexIter<'search, 'graph>
466        = VertexIter<'search, 'graph, Self>
467    where
468        Self: 'graph;
469
470    fn add_vertex(&mut self, vertex: Self::Vertex) -> Self::VertexId {
471        // Get the label index from the vertex
472        let label_idx = vertex.label().ordinal();
473
474        // Get the corresponding LabelledVertices for this label
475        let labelled_vertices = &mut self.vertices[label_idx];
476
477        // Add the vertex to the label-specific storage and get its index
478        let vertex_idx = labelled_vertices.add(vertex, &mut self.indexes);
479
480        VertexId::new(label_idx as u16, vertex_idx)
481    }
482
483    fn add_edge(
484        &mut self,
485        from: Self::VertexId,
486        to: Self::VertexId,
487        edge: Self::Edge,
488    ) -> Self::EdgeId {
489        // 1. Get the label index from the edge
490        let label_idx = edge.label().ordinal();
491
492        // 2. Get the corresponding LabelledEdges for this label
493        let labelled_edges = &mut self.edges[label_idx];
494
495        // 3. Add the edge to the label-specific storage and get its index
496        let edge_idx = labelled_edges.add(edge);
497
498        let edge_id = EdgeId::new(label_idx as u16, edge_idx, from, to);
499
500        // Add the edges to the adjacency lists for the vertices.
501        let tail_vertex_label = &mut self.vertices[from.label() as usize];
502        tail_vertex_label.add_adjacency(from.vertex(), Adjacency::outgoing(&edge_id));
503        let head_vertex_label = &mut self.vertices[to.label() as usize];
504        head_vertex_label.add_adjacency(to.vertex(), Adjacency::incoming(&edge_id));
505
506        edge_id
507    }
508
509    fn remove_vertex(&mut self, id: Self::VertexId) -> Option<Self::Vertex> {
510        let label_idx = id.label();
511        let vertex_idx = id.vertex();
512
513        // Get the corresponding LabelledVertices for this label
514        let labelled_vertices = &mut self.vertices[label_idx as usize];
515        // Remove the vertex and return it
516        if let Some(vertex_storage) = labelled_vertices.remove(vertex_idx, &mut self.indexes) {
517            // Remove the edges from the adjacency lists for the vertices.
518            for adjacency in &vertex_storage.adjacency_list {
519                let vertex_label = &mut self.vertices[adjacency.vertex_label as usize];
520                vertex_label.remove_adjacency(adjacency.vertex_id, &adjacency.reversed(id));
521                self.edges[adjacency.edge_label as usize].remove(adjacency.edge_id);
522            }
523            return Some(vertex_storage.weight);
524        }
525        None
526    }
527
528    fn remove_edge(&mut self, edge: Self::EdgeId) -> Option<Self::Edge> {
529        let label_idx = edge.label() as usize;
530        let edge_idx = edge.edge();
531
532        // Get the corresponding LabelledEdges for this label
533        let labelled_edges = &mut self.edges[label_idx];
534
535        // Remove the edge from both vertex adjacency lists
536        let tail_vertices = &mut self.vertices[edge.tail().label() as usize];
537        tail_vertices.remove_adjacency(edge.tail().vertex(), &Adjacency::outgoing(&edge));
538
539        let head_vertices = &mut self.vertices[edge.head().label() as usize];
540        head_vertices.remove_adjacency(edge.head().vertex(), &Adjacency::incoming(&edge));
541
542        // Remove and return the edge
543        labelled_edges.remove(edge_idx)
544    }
545
546    fn vertex(&self, id: Self::VertexId) -> Option<Self::VertexReference<'_>> {
547        let label_idx = id.label();
548        let vertex_idx = id.vertex();
549
550        // Get the corresponding LabelledVertices for this label
551        let labelled_vertices = &self.vertices[label_idx as usize];
552
553        // Get the vertex and create a reference if it exists
554        labelled_vertices
555            .get(vertex_idx)
556            .map(|weight| VertexReference { id, weight })
557    }
558
559    fn vertex_mut(&mut self, id: Self::VertexId) -> Option<Self::VertexReferenceMut<'_>> {
560        let label_idx = id.label();
561        let vertex_idx = id.vertex();
562
563        // Get the corresponding LabelledVertices for this label
564        let labelled_vertices = self.vertices.get_mut(label_idx as usize)?;
565
566        // Get mutable reference to the vertex if it exists
567        let vertex = labelled_vertices.get_mut(vertex_idx);
568        vertex.map(|weight| VertexReferenceMut {
569            indexes: &mut self.indexes,
570            id,
571            weight,
572        })
573    }
574
575    fn vertices<'search>(
576        &self,
577        search: &VertexSearch<'search, Self>,
578    ) -> Self::VertexIter<'search, '_> {
579        let iter: SmallBox<dyn Iterator<Item = VertexId> + '_, S8> = match search {
580            VertexSearch::Scan { .. } => {
581                // Start iterating through the first group; the iterator will handle the rest
582                smallbox!(
583                    self.vertices
584                        .iter()
585                        .enumerate()
586                        .flat_map(|(ordinal, label)| label
587                            .iter()
588                            .map(move |idx| VertexId::new(ordinal as u16, idx)))
589                )
590            }
591            VertexSearch::Label { label, .. } => {
592                // Only iterate over vertices for the specified label
593                let label_ordinal = label.ordinal() as u16;
594                smallbox!(
595                    self.vertices[label.ordinal()]
596                        .iter()
597                        .map(move |idx| VertexId::new(label_ordinal, idx))
598                )
599            }
600            VertexSearch::Index { index, value, .. } => {
601                let index_storage = &self.indexes[index.ordinal()];
602                index_storage.get(value, index)
603            }
604            VertexSearch::Range { index, range, .. } => {
605                let index_storage = &self.indexes[index.ordinal()];
606                index_storage.range(range, index)
607            }
608            VertexSearch::FullText { index, search, .. } => {
609                let index_storage = &self.indexes[index.ordinal()];
610                index_storage.get(search, index)
611            }
612            _ => unreachable!("Non-exhaustive enum, but all cases covered"),
613        };
614
615        VertexIter {
616            _phantom: Default::default(),
617            vertices: &self.vertices,
618            iter,
619            count: 0,
620            limit: search.limit(),
621        }
622    }
623
624    fn edge(&self, id: Self::EdgeId) -> Option<Self::EdgeReference<'_>> {
625        let label_idx = id.label();
626        let edge_idx = id.edge();
627
628        // Get the corresponding LabelledEdges for this label
629        let labelled_edges = &self.edges[label_idx as usize];
630
631        // Get the edge and create a reference if it exists
632        labelled_edges
633            .get(edge_idx)
634            .map(|weight| EdgeReference { id, weight })
635    }
636
637    fn edge_mut(&mut self, edge: Self::EdgeId) -> Option<Self::EdgeReferenceMut<'_>> {
638        let label_idx = edge.label();
639        let edge_idx = edge.edge();
640
641        // Get the corresponding LabelledEdges for this label
642        let labelled_edges = &mut self.edges[label_idx as usize];
643
644        // Get mutable reference to the edge if it exists
645        labelled_edges
646            .get_mut(edge_idx)
647            .map(|weight| EdgeReferenceMut {
648                id: edge,
649                tail: edge.tail(),
650                head: edge.head(),
651                weight,
652            })
653    }
654
655    fn edges<'search>(
656        &self,
657        vertex: Self::VertexId,
658        search: &EdgeSearch<'search, Self>,
659    ) -> Self::EdgeIter<'search, '_> {
660        // The edges are stored in a BTreeSet so they are already sorted. If we have a label in the search we can use this to create a range iterator using VertexStorage.
661
662        let labelled_vertices = &self.vertices[vertex.label() as usize];
663        let vertex_storage = &labelled_vertices[vertex.vertex()];
664
665        // In reverse order of specitivity we populate the ranges.
666        // This is because for instance if you have a specific range for a label you will need to iterate
667        // over each direction individually rather than using the full range.
668        let adjacent_label_range = search
669            .adjacent_label
670            .map(|label| label.ordinal() as u16..label.ordinal() as u16 + 1);
671        let label_range = search
672            .label
673            .map(|label| label.ordinal() as u16..label.ordinal() as u16 + 1)
674            .or_else(|| adjacent_label_range.as_ref().map(|_| 0..u16::MAX));
675        let direction_range = match search.direction {
676            Direction::All => Direction::Outgoing..Direction::All,
677            Direction::Outgoing => Direction::Outgoing..Direction::Incoming,
678            Direction::Incoming => Direction::Incoming..Direction::All,
679        };
680
681        // Now flatmap all the ranges together.
682        // This gives an iterator that can be used to generate iterators of adjacency.
683        let range_iter = RangeOrNoneIterator::new(Some(direction_range), |d| match d {
684            Direction::Outgoing => Direction::Incoming,
685            Direction::Incoming => Direction::All,
686            Direction::All => unreachable!("range should never include all"),
687        })
688        .flat_map(move |direction| {
689            RangeOrNoneIterator::new(label_range.clone(), |l| l + 1)
690                .map(move |label| (direction, label))
691        })
692        .flat_map(move |(direction, label)| {
693            RangeOrNoneIterator::new(adjacent_label_range.clone(), |l| l + 1)
694                .map(move |adjacent_label| (direction, label, adjacent_label))
695        });
696        let range_iter: BoxedRangeIter = smallbox::smallbox!(range_iter);
697        assert!(!range_iter.is_heap());
698        EdgeIter {
699            _phantom: Default::default(),
700            vertex,
701            vertex_storage,
702            edges: &self.edges,
703            range_iter,
704            current_iter: None,
705            count: 0,
706            limit: search.limit(),
707        }
708    }
709
710    // Clear method moved to SupportsClear implementation
711}
712
713// Implement all the support traits for SimpleGraph
714impl<Vertex, Edge> SupportsVertexLabelIndex for SimpleGraph<Vertex, Edge>
715where
716    Vertex: Element,
717    Edge: Element,
718{
719}
720
721impl<Vertex, Edge> SupportsEdgeLabelIndex for SimpleGraph<Vertex, Edge>
722where
723    Vertex: Element,
724    Edge: Element,
725{
726}
727
728impl<Vertex, Edge> SupportsVertexHashIndex for SimpleGraph<Vertex, Edge>
729where
730    Vertex: Element,
731    Edge: Element,
732{
733}
734
735impl<Vertex, Edge> SupportsEdgeHashIndex for SimpleGraph<Vertex, Edge>
736where
737    Vertex: Element,
738    Edge: Element,
739{
740}
741
742impl<Vertex, Edge> SupportsVertexRangeIndex for SimpleGraph<Vertex, Edge>
743where
744    Vertex: Element,
745    Edge: Element,
746{
747}
748
749impl<Vertex, Edge> SupportsEdgeRangeIndex for SimpleGraph<Vertex, Edge>
750where
751    Vertex: Element,
752    Edge: Element,
753{
754}
755
756impl<Vertex, Edge> SupportsVertexFullTextIndex for SimpleGraph<Vertex, Edge>
757where
758    Vertex: Element,
759    Edge: Element,
760{
761}
762
763impl<Vertex, Edge> SupportsEdgeAdjacentLabelIndex for SimpleGraph<Vertex, Edge>
764where
765    Vertex: Element,
766    Edge: Element,
767{
768}
769
770impl<Vertex, Edge> SupportsClear for SimpleGraph<Vertex, Edge>
771where
772    Vertex: Element,
773    Edge: Element,
774{
775    fn clear(&mut self) {
776        // Clear all vertex storages
777        for labelled_vertices in &mut self.vertices {
778            labelled_vertices.clear();
779        }
780
781        // Clear all edge storages
782        for edge_label in &mut self.edges {
783            edge_label.clear();
784        }
785    }
786}