1use core::fmt;
20
21#[cfg(feature = "serde")]
22use serde::{Deserialize, Serialize};
23
24use crate::edge::{EdgeIndex, EdgeRef, EdgeStorage};
25use crate::errors::{GraphError, GraphResult};
26use crate::graph::traits::{GraphBase, GraphOps, GraphQuery};
27use crate::node::{NodeIndex, NodeRef, NodeSlot};
28
29#[derive(Clone, Debug)]
32#[repr(align(64))]
33#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
34pub(crate) struct AdjBucket {
35 neighbors: Vec<usize>,
36 edge_indices: Vec<usize>,
37 deleted_mask: Vec<u64>,
38 deleted_count: usize,
39 _padding: [u8; 8], }
41
42impl AdjBucket {
43 fn new() -> Self {
44 Self {
45 neighbors: Vec::new(),
46 edge_indices: Vec::new(),
47 deleted_mask: Vec::new(),
48 deleted_count: 0,
49 _padding: [0; 8],
50 }
51 }
52
53 #[inline]
54 fn push(&mut self, target: usize, edge_idx: usize) {
55 self.neighbors.push(target);
56 self.edge_indices.push(edge_idx);
57 let bit_idx = self.neighbors.len() - 1;
58 let word_idx = bit_idx / 64;
59 while self.deleted_mask.len() <= word_idx {
60 self.deleted_mask.push(0);
61 }
62 }
63
64 #[inline]
65 fn mark_deleted(&mut self, pos: usize) {
66 let word_idx = pos / 64;
67 let bit = pos % 64;
68 if word_idx < self.deleted_mask.len() {
69 let mask = 1u64 << bit;
70 if self.deleted_mask[word_idx] & mask == 0 {
71 self.deleted_mask[word_idx] |= mask;
72 self.deleted_count += 1;
73 }
74 }
75 }
76
77 #[inline]
78 fn is_deleted(&self, pos: usize) -> bool {
79 let word_idx = pos / 64;
80 let bit = pos % 64;
81 if word_idx >= self.deleted_mask.len() {
82 return false;
83 }
84 self.deleted_mask[word_idx] & (1u64 << bit) != 0
85 }
86
87 #[inline]
88 fn compact(&mut self) {
89 if self.deleted_count == 0 {
90 return;
91 }
92 let mut write_pos = 0;
93 for read_pos in 0..self.neighbors.len() {
94 if !self.is_deleted(read_pos) {
95 if write_pos != read_pos {
96 self.neighbors[write_pos] = self.neighbors[read_pos];
97 self.edge_indices[write_pos] = self.edge_indices[read_pos];
98 }
99 write_pos += 1;
100 }
101 }
102 self.neighbors.truncate(write_pos);
103 self.edge_indices.truncate(write_pos);
104 let words_needed = write_pos.div_ceil(64);
105 self.deleted_mask.truncate(words_needed);
106 for w in self.deleted_mask.iter_mut() {
107 *w = 0;
108 }
109 self.deleted_count = 0;
110 }
111
112 #[inline]
113 fn find(&self, target: usize) -> Option<usize> {
114 self.neighbors
115 .iter()
116 .position(|&n| n == target)
117 .filter(|&pos| !self.is_deleted(pos))
118 }
119
120 #[inline]
121 fn len(&self) -> usize {
122 self.neighbors.len() - self.deleted_count
123 }
124
125 #[inline]
126 fn iter(&self) -> AdjBucketIter<'_> {
127 AdjBucketIter {
128 bucket: self,
129 pos: 0,
130 }
131 }
132
133 #[inline]
135 fn snapshot(&self) -> Vec<(usize, usize)> {
136 self.iter().collect()
137 }
138}
139
140pub(crate) struct AdjBucketIter<'a> {
142 bucket: &'a AdjBucket,
143 pos: usize,
144}
145
146impl<'a> Iterator for AdjBucketIter<'a> {
147 type Item = (usize, usize); #[inline]
150 fn next(&mut self) -> Option<Self::Item> {
151 while self.pos < self.bucket.neighbors.len() {
152 #[cfg(all(feature = "unstable", target_feature = "sse"))]
155 {
156 use core::arch::x86_64::_mm_prefetch;
157 use core::arch::x86_64::_MM_HINT_T0;
158
159 let prefetch_pos = self.pos + 4;
160 if prefetch_pos < self.bucket.neighbors.len() {
161 unsafe {
165 _mm_prefetch(
166 self.bucket.neighbors.as_ptr().add(prefetch_pos) as *const i8,
167 _MM_HINT_T0,
168 );
169 _mm_prefetch(
170 self.bucket.edge_indices.as_ptr().add(prefetch_pos) as *const i8,
171 _MM_HINT_T0,
172 );
173 }
174 }
175 }
176
177 let pos = self.pos;
178 self.pos += 1;
179 if !self.bucket.is_deleted(pos) {
180 return Some((self.bucket.neighbors[pos], self.bucket.edge_indices[pos]));
181 }
182 }
183 None
184 }
185}
186
187pub struct NeighborsIter {
191 snapshot: std::vec::IntoIter<(usize, u32)>,
193}
194
195impl NeighborsIter {
196 pub(crate) fn new(snapshot: Vec<(usize, u32)>) -> Self {
197 Self {
198 snapshot: snapshot.into_iter(),
199 }
200 }
201}
202
203impl Iterator for NeighborsIter {
204 type Item = NodeIndex;
205
206 #[inline]
207 fn next(&mut self) -> Option<Self::Item> {
208 self.snapshot
209 .next()
210 .map(|(idx, generation)| NodeIndex::new(idx, generation))
211 }
212}
213
214pub struct IncidentEdgesIter {
218 snapshot: std::vec::IntoIter<(usize, u32)>,
220}
221
222impl IncidentEdgesIter {
223 pub(crate) fn new(snapshot: Vec<(usize, u32)>) -> Self {
224 Self {
225 snapshot: snapshot.into_iter(),
226 }
227 }
228}
229
230impl Iterator for IncidentEdgesIter {
231 type Item = EdgeIndex;
232
233 #[inline]
234 fn next(&mut self) -> Option<Self::Item> {
235 self.snapshot
236 .next()
237 .map(|(idx, generation)| EdgeIndex::new(idx, generation))
238 }
239}
240
241#[derive(Clone, Debug)]
251#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
252pub(crate) struct AdjacencyBuckets {
253 buckets: Vec<AdjBucket>,
254 reverse_buckets: Vec<AdjBucket>,
255 num_nodes: usize,
256 needs_compact: bool,
257}
258
259#[deprecated(
264 since = "0.3.1",
265 note = "使用 AdjacencyBuckets 代替,命名更准确反映实现"
266)]
267#[allow(dead_code)]
268pub(crate) type CsrStorage = AdjacencyBuckets;
269
270impl AdjacencyBuckets {
271 pub(crate) fn new() -> Self {
272 let this = Self {
273 buckets: Vec::new(),
274 reverse_buckets: Vec::new(),
275 num_nodes: 0,
276 needs_compact: false,
277 };
278 debug_assert_eq!(
280 this.buckets.as_ptr() as usize % 64,
281 0,
282 "buckets 初始对齐失败"
283 );
284 debug_assert_eq!(
285 this.reverse_buckets.as_ptr() as usize % 64,
286 0,
287 "reverse_buckets 初始对齐失败"
288 );
289 this
290 }
291
292 #[inline]
301 pub(crate) fn assert_aligned(&self) {
302 let buckets_ptr = self.buckets.as_ptr() as usize;
303 let reverse_ptr = self.reverse_buckets.as_ptr() as usize;
304 assert_eq!(
305 buckets_ptr % 64,
306 0,
307 "AdjacencyBuckets: buckets 未 64 字节对齐 (ptr={:#x}, mod={})",
308 buckets_ptr,
309 buckets_ptr % 64
310 );
311 assert_eq!(
312 reverse_ptr % 64,
313 0,
314 "AdjacencyBuckets: reverse_buckets 未 64 字节对齐 (ptr={:#x}, mod={})",
315 reverse_ptr,
316 reverse_ptr % 64
317 );
318 }
319
320 pub(crate) fn reserve(&mut self, nodes: usize, _edges: usize) {
321 self.buckets.reserve(nodes);
322 self.reverse_buckets.reserve(nodes);
323 self.assert_aligned();
325 }
326
327 fn ensure_capacity(&mut self, node_index: usize) {
328 while self.buckets.len() <= node_index {
329 self.buckets.push(AdjBucket::new());
330 }
331 while self.reverse_buckets.len() <= node_index {
332 self.reverse_buckets.push(AdjBucket::new());
333 }
334 self.num_nodes = self.buckets.len();
335 self.assert_aligned();
337 }
338
339 pub(crate) fn add_edge(&mut self, node_index: usize, target_index: usize, edge_index: usize) {
341 self.ensure_capacity(node_index.max(target_index));
342 self.buckets[node_index].push(target_index, edge_index);
343 self.reverse_buckets[target_index].push(node_index, edge_index);
344 }
345
346 pub(crate) fn mark_edge_deleted(&mut self, node_index: usize, target_index: usize) {
348 if let Some(pos) = self.buckets[node_index].find(target_index) {
349 self.buckets[node_index].mark_deleted(pos);
350 self.needs_compact = true;
351 }
352 if let Some(pos) = self.reverse_buckets[target_index].find(node_index) {
353 self.reverse_buckets[target_index].mark_deleted(pos);
354 }
355 }
356
357 pub(crate) fn compact(&mut self) {
358 if !self.needs_compact {
359 return;
360 }
361 for bucket in &mut self.buckets {
362 bucket.compact();
363 }
364 for bucket in &mut self.reverse_buckets {
365 bucket.compact();
366 }
367 self.needs_compact = false;
368 }
369
370 #[allow(dead_code)]
371 pub(crate) fn neighbors_raw(&self, node_index: usize) -> impl Iterator<Item = usize> + '_ {
372 self.buckets
373 .get(node_index)
374 .into_iter()
375 .flat_map(|b| b.iter())
376 .map(move |(target_idx, _)| target_idx)
377 }
378
379 #[allow(dead_code)]
380 pub(crate) fn reverse_neighbors_raw(
381 &self,
382 node_index: usize,
383 ) -> impl Iterator<Item = usize> + '_ {
384 self.reverse_buckets
385 .get(node_index)
386 .into_iter()
387 .flat_map(|b| b.iter())
388 .map(move |(src_idx, _)| src_idx)
389 }
390
391 pub(crate) fn edge_indices_iter(&self, node_index: usize) -> impl Iterator<Item = usize> + '_ {
392 self.buckets
393 .get(node_index)
394 .into_iter()
395 .flat_map(|b| b.iter().map(|(_, ei)| ei))
396 }
397
398 pub(crate) fn edge_indices_snapshot(&self, node_index: usize) -> Vec<usize> {
400 self.edge_indices_iter(node_index).collect()
401 }
402
403 pub(crate) fn neighbors_snapshot(&self, node_index: usize) -> Vec<(usize, usize)> {
405 self.buckets
406 .get(node_index)
407 .map(|b| b.snapshot())
408 .unwrap_or_default()
409 }
410
411 pub(crate) fn has_edge(&self, node_index: usize, target_index: usize) -> bool {
412 self.buckets
413 .get(node_index)
414 .and_then(|b| b.find(target_index))
415 .is_some()
416 }
417
418 pub(crate) fn degree(&self, node_index: usize) -> usize {
419 self.buckets.get(node_index).map(|b| b.len()).unwrap_or(0)
420 }
421
422 pub(crate) fn in_degree(&self, node_index: usize) -> usize {
423 self.reverse_buckets
424 .get(node_index)
425 .map(|b| b.len())
426 .unwrap_or(0)
427 }
428
429 pub(crate) fn reverse_edge_indices_iter(
430 &self,
431 node_index: usize,
432 ) -> impl Iterator<Item = usize> + '_ {
433 self.reverse_buckets
434 .get(node_index)
435 .into_iter()
436 .flat_map(|b| b.iter().map(|(_, ei)| ei))
437 }
438
439 pub(crate) fn clear(&mut self) {
440 self.buckets.clear();
441 self.reverse_buckets.clear();
442 self.num_nodes = 0;
443 self.needs_compact = false;
444 }
445
446 #[allow(dead_code)]
447 pub(crate) fn num_nodes(&self) -> usize {
448 self.num_nodes
449 }
450}
451
452impl Default for AdjacencyBuckets {
453 fn default() -> Self {
454 Self::new()
455 }
456}
457
458#[derive(Clone)]
461#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
462#[cfg_attr(
463 feature = "serde",
464 serde(bound(
465 serialize = "T: Serialize, E: Serialize",
466 deserialize = "T: Deserialize<'de>, E: Deserialize<'de>"
467 ))
468)]
469pub struct Graph<T, E> {
470 nodes: Vec<NodeSlot<T>>,
471 edges: Vec<EdgeStorage<E>>,
472 csr: AdjacencyBuckets,
473 node_count: usize,
474 edge_count: usize,
475 free_nodes: Vec<usize>,
476 free_edges: Vec<usize>,
477}
478
479impl<T, E> fmt::Debug for Graph<T, E>
480where
481 T: fmt::Debug,
482 E: fmt::Debug,
483{
484 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
485 f.debug_struct("Graph")
486 .field("node_count", &self.node_count)
487 .field("edge_count", &self.edge_count)
488 .finish()
489 }
490}
491
492impl<T, E> Graph<T, E> {
493 pub fn directed() -> Self {
495 Self {
496 nodes: Vec::new(),
497 edges: Vec::new(),
498 csr: AdjacencyBuckets::new(),
499 node_count: 0,
500 edge_count: 0,
501 free_nodes: Vec::new(),
502 free_edges: Vec::new(),
503 }
504 }
505
506 pub fn undirected() -> Self {
508 Self::directed()
509 }
510
511 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
513 let mut graph = Self::directed();
514 graph.reserve(nodes, edges);
515 graph
516 }
517
518 #[inline]
520 pub fn is_empty(&self) -> bool {
521 self.node_count == 0
522 }
523
524 pub fn clear(&mut self) {
526 self.nodes.clear();
527 self.edges.clear();
528 self.csr.clear();
529 self.node_count = 0;
530 self.edge_count = 0;
531 self.free_nodes.clear();
532 self.free_edges.clear();
533 }
534
535 pub fn get_edge_by_nodes(&self, from: NodeIndex, to: NodeIndex) -> GraphResult<&E> {
537 for edge_idx in self.csr.edge_indices_iter(from.index()) {
538 if edge_idx < self.edges.len() {
539 let edge = &self.edges[edge_idx];
540 if edge.is_occupied() && edge.target == to {
541 return edge
542 .data()
543 .ok_or(GraphError::EdgeNotFound { index: edge_idx });
544 }
545 }
546 }
547 Err(GraphError::EdgeNotFound { index: usize::MAX })
548 }
549}
550
551impl<T, E> GraphBase for Graph<T, E> {
552 type NodeData = T;
553 type EdgeData = E;
554
555 #[inline]
556 fn node_count(&self) -> usize {
557 self.node_count
558 }
559
560 #[inline]
561 fn edge_count(&self) -> usize {
562 self.edge_count
563 }
564
565 #[inline]
566 fn contains_node(&self, index: NodeIndex) -> bool {
567 if index.index() >= self.nodes.len() {
568 return false;
569 }
570 let slot = &self.nodes[index.index()];
571 slot.is_occupied() && slot.generation == index.generation()
572 }
573
574 #[inline]
575 fn contains_edge(&self, index: EdgeIndex) -> bool {
576 if index.index() >= self.edges.len() {
577 return false;
578 }
579 let edge = &self.edges[index.index()];
580 edge.is_occupied() && edge.generation == index.generation()
581 }
582}
583
584impl<T, E> GraphQuery for Graph<T, E> {
585 #[inline]
586 fn get_node(&self, index: NodeIndex) -> GraphResult<&T> {
587 if index.index() >= self.nodes.len() {
588 return Err(GraphError::NodeNotFound {
589 index: index.index(),
590 });
591 }
592 let slot = &self.nodes[index.index()];
593 if !slot.is_occupied() {
594 return Err(GraphError::NodeNotFound {
595 index: index.index(),
596 });
597 }
598 if slot.generation != index.generation() {
599 return Err(GraphError::NodeDeleted {
600 index: index.index(),
601 provided: index.generation(),
602 current: slot.generation,
603 });
604 }
605 slot.data().ok_or(GraphError::NodeNotFound {
606 index: index.index(),
607 })
608 }
609
610 #[inline]
611 fn get_edge(&self, index: EdgeIndex) -> GraphResult<&E> {
612 if index.index() >= self.edges.len() {
613 return Err(GraphError::EdgeNotFound {
614 index: index.index(),
615 });
616 }
617 let edge = &self.edges[index.index()];
618 if !edge.is_occupied() {
619 return Err(GraphError::EdgeNotFound {
620 index: index.index(),
621 });
622 }
623 if edge.generation != index.generation() {
624 return Err(GraphError::EdgeDeleted {
625 index: index.index(),
626 provided: index.generation(),
627 current: edge.generation,
628 });
629 }
630 edge.data().ok_or(GraphError::EdgeNotFound {
631 index: index.index(),
632 })
633 }
634
635 #[inline]
636 fn edge_endpoints(&self, index: EdgeIndex) -> GraphResult<(NodeIndex, NodeIndex)> {
637 if index.index() >= self.edges.len() {
638 return Err(GraphError::EdgeNotFound {
639 index: index.index(),
640 });
641 }
642 let edge = &self.edges[index.index()];
643 if !edge.is_occupied() {
644 return Err(GraphError::EdgeNotFound {
645 index: index.index(),
646 });
647 }
648 if edge.generation != index.generation() {
649 return Err(GraphError::EdgeDeleted {
650 index: index.index(),
651 provided: index.generation(),
652 current: edge.generation,
653 });
654 }
655 Ok((edge.source, edge.target))
656 }
657
658 #[inline]
682 fn neighbors(&self, node: NodeIndex) -> impl Iterator<Item = NodeIndex> {
683 let node_index = node.index();
684 let snapshot: Vec<(usize, u32)> = self
686 .csr
687 .neighbors_snapshot(node_index)
688 .into_iter()
689 .map(|(target_idx, _edge_idx)| {
690 let generation = self
691 .nodes
692 .get(target_idx)
693 .map(|n| n.generation)
694 .unwrap_or(0);
695 (target_idx, generation)
696 })
697 .collect();
698 NeighborsIter::new(snapshot)
699 }
700
701 #[inline]
725 fn incident_edges(&self, node: NodeIndex) -> impl Iterator<Item = EdgeIndex> {
726 let node_index = node.index();
727 let snapshot: Vec<(usize, u32)> = self
729 .csr
730 .edge_indices_snapshot(node_index)
731 .into_iter()
732 .map(|edge_idx| {
733 let generation = self.edges.get(edge_idx).map(|e| e.generation).unwrap_or(0);
734 (edge_idx, generation)
735 })
736 .collect();
737 IncidentEdgesIter::new(snapshot)
738 }
739
740 #[inline]
741 fn has_edge(&self, from: NodeIndex, to: NodeIndex) -> bool {
742 self.csr.has_edge(from.index(), to.index())
743 }
744
745 #[inline]
746 fn out_degree(&self, node: NodeIndex) -> GraphResult<usize> {
747 if !self.contains_node(node) {
748 return Err(GraphError::NodeNotFound {
749 index: node.index(),
750 });
751 }
752 Ok(self.csr.degree(node.index()))
753 }
754
755 #[inline]
756 fn in_degree(&self, node: NodeIndex) -> GraphResult<usize> {
757 if !self.contains_node(node) {
758 return Err(GraphError::NodeNotFound {
759 index: node.index(),
760 });
761 }
762 Ok(self.csr.in_degree(node.index()))
763 }
764
765 #[inline]
766 fn degree(&self, node: NodeIndex) -> GraphResult<usize> {
767 let out_deg = self.out_degree(node)?;
768 let in_deg = self.in_degree(node)?;
769 Ok(out_deg + in_deg)
770 }
771
772 #[inline]
773 fn nodes(&self) -> impl Iterator<Item = NodeRef<'_, T>> {
774 self.nodes.iter().enumerate().filter_map(|(idx, slot)| {
775 if slot.is_occupied() {
776 Some(NodeRef::new(
777 NodeIndex::new(idx, slot.generation),
778 slot.data()?,
779 ))
780 } else {
781 None
782 }
783 })
784 }
785
786 #[inline]
787 fn edges(&self) -> impl Iterator<Item = EdgeRef<'_, E>> {
788 self.edges.iter().enumerate().filter_map(|(idx, edge)| {
789 if edge.is_occupied() {
790 Some(EdgeRef::new(
791 EdgeIndex::new(idx, edge.generation),
792 edge.source,
793 edge.target,
794 edge.data()?,
795 ))
796 } else {
797 None
798 }
799 })
800 }
801}
802
803impl<T, E> GraphOps for Graph<T, E> {
804 #[inline]
805 fn add_node(&mut self, data: T) -> GraphResult<NodeIndex> {
806 let (index, generation) = if let Some(free_idx) = self.free_nodes.pop() {
807 let slot = &mut self.nodes[free_idx];
808 let new_generation = slot.generation.wrapping_add(1);
809 *slot = NodeSlot::new(new_generation, data);
810 (free_idx, new_generation)
811 } else {
812 let index = self.nodes.len();
813 let generation = 1u32;
814 self.nodes.push(NodeSlot::new(generation, data));
815 (index, generation)
816 };
817
818 self.node_count += 1;
819 self.csr.ensure_capacity(index);
820 Ok(NodeIndex::new(index, generation))
821 }
822
823 #[inline]
824 fn remove_node(&mut self, index: NodeIndex) -> GraphResult<T> {
825 if index.index() >= self.nodes.len() {
826 return Err(GraphError::NodeNotFound {
827 index: index.index(),
828 });
829 }
830
831 let slot = &mut self.nodes[index.index()];
832 if !slot.is_occupied() {
833 return Err(GraphError::NodeNotFound {
834 index: index.index(),
835 });
836 }
837 if slot.generation != index.generation() {
838 return Err(GraphError::NodeDeleted {
839 index: index.index(),
840 provided: index.generation(),
841 current: slot.generation,
842 });
843 }
844
845 let edge_indices: Vec<usize> = self.csr.edge_indices_iter(index.index()).collect();
847 for edge_idx in edge_indices {
848 if edge_idx < self.edges.len() {
849 let edge = &self.edges[edge_idx];
850 if edge.is_occupied() {
851 self.csr
852 .mark_edge_deleted(index.index(), edge.target.index());
853 let edge_slot = &mut self.edges[edge_idx];
854 edge_slot.data = None;
855 self.edge_count -= 1;
856 self.free_edges.push(edge_idx);
857 }
858 }
859 }
860
861 let incoming: Vec<usize> = self.csr.reverse_edge_indices_iter(index.index()).collect();
863 for edge_idx in incoming {
864 if edge_idx < self.edges.len() {
865 let edge = &self.edges[edge_idx];
866 if edge.is_occupied() {
867 self.csr
868 .mark_edge_deleted(edge.source.index(), index.index());
869 let edge_slot = &mut self.edges[edge_idx];
870 edge_slot.data = None;
871 self.edge_count -= 1;
872 self.free_edges.push(edge_idx);
873 }
874 }
875 }
876
877 self.csr.compact();
878
879 let data = slot.data.take().ok_or(GraphError::NodeNotFound {
880 index: index.index(),
881 })?;
882 self.node_count -= 1;
883 self.free_nodes.push(index.index());
884
885 Ok(data)
886 }
887
888 #[inline]
889 fn add_edge(&mut self, from: NodeIndex, to: NodeIndex, data: E) -> GraphResult<EdgeIndex> {
890 if !self.contains_node(from) {
891 return Err(GraphError::NodeNotFound {
892 index: from.index(),
893 });
894 }
895 if !self.contains_node(to) {
896 return Err(GraphError::NodeNotFound { index: to.index() });
897 }
898
899 let (index, generation) = if let Some(free_idx) = self.free_edges.pop() {
900 let edge = &mut self.edges[free_idx];
901 let new_generation = edge.generation.wrapping_add(1);
902 *edge = EdgeStorage::new(from, to, data, new_generation);
903 (free_idx, new_generation)
904 } else {
905 let index = self.edges.len();
906 let generation = 1u32;
907 self.edges
908 .push(EdgeStorage::new(from, to, data, generation));
909 (index, generation)
910 };
911
912 self.edge_count += 1;
913 self.csr.add_edge(from.index(), to.index(), index);
914 Ok(EdgeIndex::new(index, generation))
915 }
916
917 #[inline]
918 fn remove_edge(&mut self, index: EdgeIndex) -> GraphResult<E> {
919 if index.index() >= self.edges.len() {
920 return Err(GraphError::EdgeNotFound {
921 index: index.index(),
922 });
923 }
924
925 let edge = &mut self.edges[index.index()];
926 if !edge.is_occupied() {
927 return Err(GraphError::EdgeNotFound {
928 index: index.index(),
929 });
930 }
931 if edge.generation != index.generation() {
932 return Err(GraphError::EdgeDeleted {
933 index: index.index(),
934 provided: index.generation(),
935 current: edge.generation,
936 });
937 }
938
939 let source_index = edge.source.index();
940 let target_index = edge.target.index();
941 self.csr.mark_edge_deleted(source_index, target_index);
942
943 let data = edge.data.take().ok_or(GraphError::EdgeNotFound {
944 index: index.index(),
945 })?;
946 self.edge_count -= 1;
947 self.free_edges.push(index.index());
948 self.csr.compact();
949
950 Ok(data)
951 }
952
953 #[inline]
954 fn update_node(&mut self, index: NodeIndex, data: T) -> GraphResult<T> {
955 if index.index() >= self.nodes.len() {
956 return Err(GraphError::NodeNotFound {
957 index: index.index(),
958 });
959 }
960
961 let slot = &mut self.nodes[index.index()];
962 if !slot.is_occupied() {
963 return Err(GraphError::NodeNotFound {
964 index: index.index(),
965 });
966 }
967 if slot.generation != index.generation() {
968 return Err(GraphError::NodeDeleted {
969 index: index.index(),
970 provided: index.generation(),
971 current: slot.generation,
972 });
973 }
974
975 let old_data = slot.data.replace(data);
976 old_data.ok_or(GraphError::NodeNotFound {
977 index: index.index(),
978 })
979 }
980
981 #[inline]
982 fn update_edge(&mut self, index: EdgeIndex, data: E) -> GraphResult<E> {
983 if index.index() >= self.edges.len() {
984 return Err(GraphError::EdgeNotFound {
985 index: index.index(),
986 });
987 }
988
989 let edge = &mut self.edges[index.index()];
990 if !edge.is_occupied() {
991 return Err(GraphError::EdgeNotFound {
992 index: index.index(),
993 });
994 }
995 if edge.generation != index.generation() {
996 return Err(GraphError::EdgeDeleted {
997 index: index.index(),
998 provided: index.generation(),
999 current: edge.generation,
1000 });
1001 }
1002
1003 let old_data = edge.data.replace(data);
1004 old_data.ok_or(GraphError::EdgeNotFound {
1005 index: index.index(),
1006 })
1007 }
1008
1009 #[inline]
1010 fn reserve(&mut self, additional_nodes: usize, additional_edges: usize) {
1011 self.nodes.reserve(additional_nodes);
1012 self.edges.reserve(additional_edges);
1013 self.csr.reserve(additional_nodes, additional_edges);
1014 }
1015
1016 #[inline]
1017 fn clear(&mut self) {
1018 Graph::clear(self);
1019 }
1020}
1021
1022impl<T, E> core::ops::Index<NodeIndex> for Graph<T, E> {
1023 type Output = T;
1024
1025 #[inline]
1026 fn index(&self, index: NodeIndex) -> &Self::Output {
1027 self.get_node(index).expect("节点索引无效")
1028 }
1029}
1030
1031impl<T, E> core::ops::IndexMut<NodeIndex> for Graph<T, E> {
1056 #[inline]
1057 fn index_mut(&mut self, index: NodeIndex) -> &mut Self::Output {
1058 if index.index() >= self.nodes.len() {
1059 panic!("节点索引无效:index={}", index.index());
1060 }
1061 let slot = &mut self.nodes[index.index()];
1062 if !slot.is_occupied() {
1063 panic!("节点索引无效:节点不存在");
1064 }
1065 if slot.generation != index.generation() {
1066 panic!("节点索引已失效:generation 不匹配");
1067 }
1068 slot.data.as_mut().expect("节点数据为空")
1069 }
1070}
1071
1072impl<T, E> core::ops::Index<EdgeIndex> for Graph<T, E> {
1073 type Output = E;
1074
1075 #[inline]
1076 fn index(&self, index: EdgeIndex) -> &Self::Output {
1077 self.get_edge(index).expect("边索引无效")
1078 }
1079}
1080
1081impl<T, E> core::ops::IndexMut<EdgeIndex> for Graph<T, E> {
1109 #[inline]
1110 fn index_mut(&mut self, index: EdgeIndex) -> &mut Self::Output {
1111 if index.index() >= self.edges.len() {
1112 panic!("边索引无效:index={}", index.index());
1113 }
1114 let edge = &mut self.edges[index.index()];
1115 if !edge.is_occupied() {
1116 panic!("边索引无效:边不存在");
1117 }
1118 if edge.generation != index.generation() {
1119 panic!("边索引已失效:generation 不匹配");
1120 }
1121 edge.data.as_mut().expect("边数据为空")
1122 }
1123}
1124
1125#[cfg(test)]
1126mod tests {
1127 use super::*;
1128
1129 #[test]
1130 fn test_graph_creation() {
1131 let graph = Graph::<i32, f64>::directed();
1132 assert_eq!(graph.node_count(), 0);
1133 assert_eq!(graph.edge_count(), 0);
1134 assert!(graph.is_empty());
1135 }
1136
1137 #[test]
1138 fn test_add_node() {
1139 let mut graph = Graph::<String, f64>::directed();
1140 let idx = graph.add_node("test".to_string()).unwrap();
1141 assert_eq!(graph.node_count(), 1);
1142 assert!(graph.contains_node(idx));
1143 assert_eq!(graph[idx], "test");
1144 }
1145
1146 #[test]
1147 fn test_index_mut() {
1148 let mut graph = Graph::<String, f64>::directed();
1149 let idx = graph.add_node("initial".to_string()).unwrap();
1150
1151 graph[idx] = "modified".to_string();
1153 assert_eq!(graph[idx], "modified");
1154
1155 let idx2 = graph.add_node("second".to_string()).unwrap();
1157 graph[idx2] = "second_modified".to_string();
1158 assert_eq!(graph[idx2], "second_modified");
1159 }
1160
1161 #[test]
1162 fn test_remove_node() {
1163 let mut graph = Graph::<i32, f64>::directed();
1164 let idx = graph.add_node(42).unwrap();
1165 assert!(graph.contains_node(idx));
1166
1167 let data = graph.remove_node(idx).unwrap();
1168 assert_eq!(data, 42);
1169 assert_eq!(graph.node_count(), 0);
1170 assert!(!graph.contains_node(idx));
1171 }
1172
1173 #[test]
1174 fn test_add_edge() {
1175 let mut graph = Graph::<i32, f64>::directed();
1176 let a = graph.add_node(1).unwrap();
1177 let b = graph.add_node(2).unwrap();
1178 let edge = graph.add_edge(a, b, std::f64::consts::PI).unwrap();
1179
1180 assert_eq!(graph.edge_count(), 1);
1181 assert!(graph.contains_edge(edge));
1182 assert_eq!(*graph.get_edge(edge).unwrap(), std::f64::consts::PI);
1183 }
1184
1185 #[test]
1186 fn test_node_reuse() {
1187 let mut graph = Graph::<i32, f64>::directed();
1188 let idx1 = graph.add_node(1).unwrap();
1189 let _ = graph.remove_node(idx1).unwrap();
1190 let idx2 = graph.add_node(2).unwrap();
1191
1192 assert_eq!(idx2.index(), idx1.index());
1193 assert!(idx2.generation() > idx1.generation());
1194 }
1195
1196 #[test]
1197 fn test_neighbors() {
1198 let mut graph = Graph::<i32, f64>::directed();
1199 let a = graph.add_node(1).unwrap();
1200 let b = graph.add_node(2).unwrap();
1201 let c = graph.add_node(3).unwrap();
1202 graph.add_edge(a, b, 1.0).unwrap();
1203 graph.add_edge(a, c, 2.0).unwrap();
1204
1205 let neighbors: Vec<_> = graph.neighbors(a).collect();
1206 assert_eq!(neighbors.len(), 2);
1207 }
1208
1209 #[test]
1210 fn test_has_edge() {
1211 let mut graph = Graph::<i32, f64>::directed();
1212 let a = graph.add_node(1).unwrap();
1213 let b = graph.add_node(2).unwrap();
1214 graph.add_edge(a, b, 1.0).unwrap();
1215
1216 assert!(graph.has_edge(a, b));
1217 assert!(!graph.has_edge(b, a));
1218 }
1219}