linkrs_storage/edge/node_group/
iter.rs1use linkrs_core::types::{Timestamp, VertexId};
10use std::collections::BTreeMap;
11
12use super::super::csr_variant::{CsrIterator, CsrRowIter};
13use super::super::Nbr;
14use super::{group_base, CsrShardSet, Shard};
15
16pub struct ShardCsrIterator<'a> {
22 shards: &'a BTreeMap<usize, Shard>,
23 order: Vec<usize>,
24 group_bits: u32,
25 group_pos: usize,
26 base: u32,
27 inner: CsrIterator<'a>,
28}
29
30impl<'a> ShardCsrIterator<'a> {
31 fn new(shards: &'a BTreeMap<usize, Shard>, group_bits: u32) -> Self {
32 Self {
33 shards,
34 order: shards.keys().copied().collect(),
35 group_bits,
36 group_pos: 0,
37 base: 0,
38 inner: CsrIterator::None,
39 }
40 }
41
42 fn advance_group(&mut self) -> bool {
43 if self.group_pos >= self.order.len() {
44 return false;
45 }
46 let gid = self.order[self.group_pos];
47 self.group_pos += 1;
48 self.base = group_base(gid, self.group_bits);
49 let Some(shard) = self.shards.get(&gid) else {
50 return self.advance_group();
51 };
52 self.inner = shard.variant.iter_all();
53 true
54 }
55}
56
57impl<'a> Iterator for ShardCsrIterator<'a> {
58 type Item = (VertexId, Nbr);
59
60 fn next(&mut self) -> Option<Self::Item> {
61 loop {
62 if let Some((local, nbr)) = self.inner.next() {
63 let Some(local) = local.as_internal_u32() else {
64 continue;
65 };
66 let global = local.saturating_add(self.base);
67 return Some((VertexId::from_u32(global), nbr));
68 }
69 if !self.advance_group() {
70 return None;
71 }
72 }
73 }
74}
75
76impl CsrShardSet {
77 pub fn iter_edges_of(&self, src_vid: u32, ts: Timestamp) -> Option<CsrRowIter<'_>> {
80 let (gid, local) = self.route(src_vid)?;
81 self.shards.get(&gid)?.variant.iter_edges_of(local, ts)
82 }
83
84 pub fn iter_all(&self) -> ShardCsrIterator<'_> {
88 ShardCsrIterator::new(&self.shards, self.group_bits)
89 }
90}