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