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
22pub struct SimpleGraph<Vertex, Edge>
24where
25 Vertex: Element,
26 Edge: Element,
27{
28 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>], iter: SmallBox<dyn Iterator<Item = VertexId> + 'graph, S8>, 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
328pub 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 let label_idx = vertex.label().ordinal();
474
475 let labelled_vertices = &mut self.vertices[label_idx];
477
478 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 let label_idx = edge.label().ordinal();
492
493 let labelled_edges = &mut self.edges[label_idx];
495
496 let edge_idx = labelled_edges.add(edge);
498
499 let edge_id = EdgeId::new(label_idx as u16, edge_idx, from, to);
500
501 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 let labelled_vertices = &self.vertices[label_idx as usize];
516
517 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 let labelled_vertices = self.vertices.get_mut(label_idx as usize)?;
529
530 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 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 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 let labelled_edges = &self.edges[label_idx as usize];
594
595 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 let labelled_edges = &mut self.edges[label_idx as usize];
607
608 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 let labelled_vertices = &self.vertices[vertex.label() as usize];
627 let vertex_storage = &labelled_vertices[vertex.vertex()];
628
629 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 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 }
676
677impl<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 for labelled_vertices in &mut self.vertices {
742 labelled_vertices.clear();
743 }
744
745 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 let labelled_vertices = &mut self.vertices[label_idx as usize];
763 if let Some(vertex_storage) = labelled_vertices.remove(vertex_idx, &mut self.indexes) {
765 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 let labelled_edges = &mut self.edges[label_idx];
782
783 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 labelled_edges.remove(edge_idx)
792 }
793}