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
21pub struct SimpleGraph<Vertex, Edge>
23where
24 Vertex: Element,
25 Edge: Element,
26{
27 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>], iter: SmallBox<dyn Iterator<Item = VertexId> + 'graph, S8>, 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
327pub 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 let label_idx = vertex.label().ordinal();
473
474 let labelled_vertices = &mut self.vertices[label_idx];
476
477 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 let label_idx = edge.label().ordinal();
491
492 let labelled_edges = &mut self.edges[label_idx];
494
495 let edge_idx = labelled_edges.add(edge);
497
498 let edge_id = EdgeId::new(label_idx as u16, edge_idx, from, to);
499
500 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 let labelled_vertices = &mut self.vertices[label_idx as usize];
515 if let Some(vertex_storage) = labelled_vertices.remove(vertex_idx, &mut self.indexes) {
517 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 let labelled_edges = &mut self.edges[label_idx];
534
535 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 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 let labelled_vertices = &self.vertices[label_idx as usize];
552
553 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 let labelled_vertices = self.vertices.get_mut(label_idx as usize)?;
565
566 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 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 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 let labelled_edges = &self.edges[label_idx as usize];
630
631 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 let labelled_edges = &mut self.edges[label_idx as usize];
643
644 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 let labelled_vertices = &self.vertices[vertex.label() as usize];
663 let vertex_storage = &labelled_vertices[vertex.vertex()];
664
665 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 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 }
712
713impl<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 for labelled_vertices in &mut self.vertices {
778 labelled_vertices.clear();
779 }
780
781 for edge_label in &mut self.edges {
783 edge_label.clear();
784 }
785 }
786}