linkrs_storage/edge/mutable_csr/
iter.rs1use std::iter::Zip;
2use std::slice::Iter as SliceIter;
3
4use linkrs_core::types::VertexId;
5
6use super::overflow::OverflowChunk;
7use super::MutableCsr;
8use crate::edge::{ColdStamps, HotNbr, Nbr};
9use linkrs_core::types::Timestamp;
10
11impl MutableCsr {
12 pub fn iter(&self, ts: Timestamp) -> MutableCsrIterator<'_> {
14 MutableCsrIterator::new(self, ts)
15 }
16
17 pub fn iter_all(&self) -> MutableCsrIterator<'_> {
21 MutableCsrIterator::new_all(self)
22 }
23
24 pub fn iter_edges_of(&self, src_vid: u32, ts: Timestamp) -> VertexEdgesIter<'_> {
30 VertexEdgesIter::new(self, src_vid, ts)
31 }
32}
33
34pub struct VertexEdgesIter<'a> {
39 primary: Zip<SliceIter<'a, HotNbr>, SliceIter<'a, ColdStamps>>,
40 ts: Timestamp,
41 overflow_chunks: Option<&'a Vec<OverflowChunk>>,
42 overflow_chunk_idx: usize,
43 overflow_edge_idx: usize,
44}
45
46impl<'a> VertexEdgesIter<'a> {
47 pub fn new(csr: &'a MutableCsr, src_vid: u32, ts: Timestamp) -> Self {
48 let (hot, cold) = csr.primary_pair(src_vid as usize);
49 Self {
50 primary: hot.iter().zip(cold.iter()),
51 ts,
52 overflow_chunks: csr.overflow_chunks.get(src_vid),
53 overflow_chunk_idx: 0,
54 overflow_edge_idx: 0,
55 }
56 }
57}
58
59impl<'a> Iterator for VertexEdgesIter<'a> {
60 type Item = Nbr;
61
62 fn next(&mut self) -> Option<Self::Item> {
63 for (hot, cold) in self.primary.by_ref() {
64 let nbr = Nbr::from_parts(*hot, *cold);
65 if nbr.is_alive_at(self.ts) {
66 return Some(nbr);
67 }
68 }
69
70 if let Some(chunks) = self.overflow_chunks {
71 while self.overflow_chunk_idx < chunks.len() {
72 let chunk = &chunks[self.overflow_chunk_idx];
73 while self.overflow_edge_idx < chunk.len() {
74 let nbr = chunk.slot_at(self.overflow_edge_idx).unwrap();
75 self.overflow_edge_idx += 1;
76 if nbr.is_alive_at(self.ts) {
77 return Some(nbr);
78 }
79 }
80 self.overflow_chunk_idx += 1;
81 self.overflow_edge_idx = 0;
82 }
83 }
84
85 None
86 }
87}
88
89pub struct MutableCsrIterator<'a> {
90 csr: &'a MutableCsr,
91 ts: Timestamp,
92 include_deleted: bool,
93 current_vertex: usize,
94 current_edge: usize,
95 in_overflow: bool,
96 overflow_chunks: Option<&'a Vec<OverflowChunk>>,
97 overflow_chunk_idx: usize,
98 overflow_edge_idx: usize,
99}
100
101impl<'a> MutableCsrIterator<'a> {
102 pub fn new(csr: &'a MutableCsr, ts: Timestamp) -> Self {
103 Self {
104 csr,
105 ts,
106 include_deleted: false,
107 current_vertex: 0,
108 current_edge: 0,
109 in_overflow: false,
110 overflow_chunks: None,
111 overflow_chunk_idx: 0,
112 overflow_edge_idx: 0,
113 }
114 }
115
116 pub fn new_all(csr: &'a MutableCsr) -> Self {
118 Self {
119 csr,
120 ts: 0,
121 include_deleted: true,
122 current_vertex: 0,
123 current_edge: 0,
124 in_overflow: false,
125 overflow_chunks: None,
126 overflow_chunk_idx: 0,
127 overflow_edge_idx: 0,
128 }
129 }
130}
131
132impl<'a> Iterator for MutableCsrIterator<'a> {
133 type Item = (VertexId, Nbr);
134
135 fn next(&mut self) -> Option<Self::Item> {
136 let csr: &'a MutableCsr = self.csr;
139 while self.current_vertex < csr.vertex_capacity() {
140 if !self.in_overflow {
141 if self.current_edge == 0 {
142 self.overflow_chunks = csr.overflow_chunks.get(self.current_vertex as u32);
143 self.overflow_chunk_idx = 0;
144 self.overflow_edge_idx = 0;
145 }
146 let (hot, cold) = csr.primary_pair(self.current_vertex);
147 while self.current_edge < hot.len() {
148 let nbr = Nbr::from_parts(hot[self.current_edge], cold[self.current_edge]);
149 self.current_edge += 1;
150 if self.include_deleted || nbr.is_alive_at(self.ts) {
151 return Some((
152 VertexId::from_u32(u32::try_from(self.current_vertex).ok()?),
153 nbr,
154 ));
155 }
156 }
157 self.in_overflow = true;
158 }
159
160 if let Some(chunks) = self.overflow_chunks {
161 while self.overflow_chunk_idx < chunks.len() {
162 let chunk = &chunks[self.overflow_chunk_idx];
163 while self.overflow_edge_idx < chunk.len() {
164 let nbr = chunk.slot_at(self.overflow_edge_idx).unwrap();
165 self.overflow_edge_idx += 1;
166 if self.include_deleted || nbr.is_alive_at(self.ts) {
167 return Some((
168 VertexId::from_u32(u32::try_from(self.current_vertex).ok()?),
169 nbr,
170 ));
171 }
172 }
173 self.overflow_chunk_idx += 1;
174 self.overflow_edge_idx = 0;
175 }
176 }
177
178 self.current_vertex += 1;
179 self.current_edge = 0;
180 self.in_overflow = false;
181 self.overflow_chunk_idx = 0;
182 self.overflow_edge_idx = 0;
183 }
184 None
185 }
186}