1#![allow(clippy::type_complexity)]
15
16use std::borrow::Borrow;
17use std::iter::Iterator;
18
19use webgraph::prelude::*;
20
21use crate::graph::{NodeId, SwhGraphWithProperties};
22use crate::labels::{EdgeLabel, UntypedEdgeLabel};
23
24pub trait IntoFlattenedLabeledArcsIterator<Label> {
25 type Flattened: IntoIterator<Item = (NodeId, Label)>;
26
27 fn flatten_labels(self) -> Self::Flattened;
30}
31
32pub struct LabeledSuccessorIterator<Successors: Iterator>
33where
34 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
35{
36 pub(crate) successors: Successors,
37}
38
39impl<Successors: Iterator> LabeledSuccessorIterator<Successors>
40where
41 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
42{
43 #[inline(always)]
44 pub fn new(successors: Successors) -> Self {
45 LabeledSuccessorIterator { successors }
46 }
47}
48
49impl<Successors: Iterator> Iterator for LabeledSuccessorIterator<Successors>
50where
51 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
52{
53 type Item = (
54 NodeId,
55 LabeledArcIterator<
56 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::IntoIter,
57 >,
58 );
59
60 fn next(&mut self) -> Option<Self::Item> {
61 self.successors.next().map(|pair| {
62 let (successor, arc_labels) = pair.into_pair();
63 (
64 successor,
65 LabeledArcIterator {
66 arc_label_ids: arc_labels.into_iter(),
67 },
68 )
69 })
70 }
71}
72
73unsafe impl<Successors: SortedIterator> SortedIterator for LabeledSuccessorIterator<Successors> where
76 <Successors as Iterator>::Item:
77 Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>, IntoIter: SortedIterator>>
78{
79}
80
81impl<Successors: Iterator> IntoFlattenedLabeledArcsIterator<UntypedEdgeLabel>
82 for LabeledSuccessorIterator<Successors>
83where
84 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
85{
86 type Flattened = FlattenedSuccessorsIterator<Self>;
87
88 #[inline(always)]
89 fn flatten_labels(self) -> Self::Flattened {
90 FlattenedSuccessorsIterator::new(self)
91 }
92}
93
94pub struct FlattenedSuccessorsIterator<Successors: Iterator + ?Sized>
95where
96 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator>,
97{
98 current_node_and_labels: Option<(
99 NodeId,
100 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::IntoIter,
101 )>,
102 iter: Successors,
103}
104
105impl<Successors: Iterator> FlattenedSuccessorsIterator<Successors>
106where
107 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator>,
108{
109 #[inline(always)]
110 pub fn new(successors: Successors) -> Self {
111 Self {
112 current_node_and_labels: None,
113 iter: successors,
114 }
115 }
116}
117
118impl<Successors: Iterator + ?Sized> Iterator for FlattenedSuccessorsIterator<Successors>
119where
120 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator>,
121{
122 type Item = (
123 NodeId,
124 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::Item,
125 );
126
127 fn next(&mut self) -> Option<Self::Item> {
128 if self.current_node_and_labels.is_none() {
129 self.current_node_and_labels = self
131 .iter
132 .next()
133 .map(Pair::into_pair)
134 .map(|(succ, labels)| (succ, labels.into_iter()))
135 }
136 let Some((current_node, ref mut current_labels)) = self.current_node_and_labels else {
137 return None;
139 };
140 match current_labels.next() {
141 Some(label) => Some((current_node, label)),
142 None => {
143 self.current_node_and_labels = None;
145 self.next()
146 }
147 }
148 }
149}
150
151unsafe impl<Successors: SortedIterator> SortedIterator for FlattenedSuccessorsIterator<Successors> where
154 <Successors as Iterator>::Item:
155 Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>, IntoIter: SortedIterator>>
156{
157}
158
159pub struct LabeledArcIterator<T: Iterator<Item: Borrow<u64>>> {
160 arc_label_ids: T,
161}
162
163impl<T: Iterator<Item: Borrow<u64>>> Iterator for LabeledArcIterator<T> {
164 type Item = UntypedEdgeLabel;
165
166 fn next(&mut self) -> Option<Self::Item> {
167 self.arc_label_ids
168 .next()
169 .map(|label| UntypedEdgeLabel::from(*label.borrow()))
170 }
171}
172
173unsafe impl<T: SortedIterator<Item: Borrow<u64>>> SortedIterator for LabeledArcIterator<T> {}
176
177pub struct LabelTypingSuccessorIterator<'a, G, Successors: Iterator>
178where
179 <Successors as Iterator>::Item:
180 Pair<Left = usize, Right: IntoIterator<Item = UntypedEdgeLabel>>,
181 G: SwhGraphWithProperties + ?Sized,
182 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
183{
184 pub(crate) graph: &'a G,
185 pub(crate) is_transposed: bool,
186 pub(crate) successors: Successors,
187 pub(crate) src: NodeId,
188}
189
190impl<'a, G, Successors: Iterator> Iterator for LabelTypingSuccessorIterator<'a, G, Successors>
191where
192 <Successors as Iterator>::Item:
193 Pair<Left = usize, Right: IntoIterator<Item = UntypedEdgeLabel>>,
194 G: SwhGraphWithProperties + ?Sized,
195 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
196{
197 type Item = (
198 NodeId,
199 LabelTypingArcIterator<
200 'a,
201 G,
202 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::IntoIter,
203 >,
204 );
205
206 fn next(&mut self) -> Option<Self::Item> {
207 self.successors.next().map(|pair| {
208 let (dst, labels) = pair.into_pair();
209 (
210 dst,
211 LabelTypingArcIterator {
212 graph: self.graph,
213 is_transposed: self.is_transposed,
214 labels: labels.into_iter(),
215 src: self.src,
216 dst,
217 },
218 )
219 })
220 }
221}
222
223impl<G, Successors: Iterator> IntoFlattenedLabeledArcsIterator<EdgeLabel>
224 for LabelTypingSuccessorIterator<'_, G, Successors>
225where
226 <Successors as Iterator>::Item:
227 Pair<Left = usize, Right: IntoIterator<Item = UntypedEdgeLabel>>,
228 G: SwhGraphWithProperties + ?Sized,
229 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
230{
231 type Flattened = FlattenedSuccessorsIterator<Self>;
232
233 #[inline(always)]
234 fn flatten_labels(self) -> Self::Flattened {
235 FlattenedSuccessorsIterator::new(self)
236 }
237}
238
239pub struct LabelTypingArcIterator<'a, G, Labels: Iterator<Item = UntypedEdgeLabel>>
240where
241 G: SwhGraphWithProperties + ?Sized,
242 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
243{
244 graph: &'a G,
245 is_transposed: bool,
246 labels: Labels,
247 src: NodeId,
248 dst: NodeId,
249}
250
251impl<G, Labels: Iterator<Item = UntypedEdgeLabel>> Iterator
252 for LabelTypingArcIterator<'_, G, Labels>
253where
254 G: SwhGraphWithProperties + ?Sized,
255 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
256{
257 type Item = EdgeLabel;
258
259 fn next(&mut self) -> Option<Self::Item> {
260 let props = self.graph.properties();
261 self.labels.next().map(move |label| {
262 label
263 .for_edge_type(
264 props.node_type(self.src),
265 props.node_type(self.dst),
266 self.is_transposed,
267 )
268 .unwrap_or_else(|e| {
269 panic!(
270 "Unexpected edge from {} ({}) to {} ({}): {}",
271 props.swhid(self.src),
272 self.src,
273 props.swhid(self.dst),
274 self.dst,
275 e
276 )
277 })
278 })
279 }
280}
281
282pub struct DelabelingIterator<Successors: Iterator<Item: Pair<Left = usize>>> {
284 pub(crate) successors: Successors,
285}
286impl<Successors: Iterator<Item: Pair<Left = usize>>> Iterator for DelabelingIterator<Successors> {
287 type Item = NodeId;
288
289 fn next(&mut self) -> Option<Self::Item> {
290 self.successors.next().map(|pair| {
291 let (successor, _arc_labels) = pair.into_pair();
292 successor
293 })
294 }
295}
296unsafe impl<Successors: SortedIterator<Item: Pair<Left = usize>>> SortedIterator
298 for DelabelingIterator<Successors>
299{
300}