persy/address/segment/
segment_page_iterator.rs

1use crate::{address::Address, id::RecRef};
2pub struct SegmentPageIterator {
3    cur_page: u64,
4    next_page: u64,
5    per_page_iterator: Vec<(u32, bool)>,
6    iter_pos: usize,
7    include_deleted: bool,
8}
9
10impl SegmentPageIterator {
11    pub fn new(first_page: u64) -> Self {
12        Self {
13            cur_page: first_page,
14            next_page: first_page,
15            per_page_iterator: vec![],
16            iter_pos: 0,
17            include_deleted: false,
18        }
19    }
20    pub fn snapshot(first_page: u64) -> Self {
21        Self {
22            cur_page: first_page,
23            next_page: first_page,
24            per_page_iterator: vec![],
25            iter_pos: 0,
26            include_deleted: true,
27        }
28    }
29
30    pub fn next(&mut self, address: &Address) -> Option<RecRef> {
31        // This loop is needed because some pages may be empty
32        loop {
33            if self.iter_pos < self.per_page_iterator.len() {
34                let (pos, exists) = self.per_page_iterator[self.iter_pos];
35                self.iter_pos += 1;
36                if exists || self.include_deleted {
37                    break Some(RecRef::new(self.cur_page, pos));
38                }
39            } else if self.next_page != 0 {
40                self.cur_page = self.next_page;
41                if let Ok((next_page, elements)) = address.scan_page_all(self.cur_page) {
42                    self.next_page = next_page;
43                    self.per_page_iterator = elements;
44                    self.iter_pos = 0;
45                }
46            } else {
47                break None;
48            }
49        }
50    }
51}