tglman / persy

Compare f977d25 ... +0 ... 0e11be4


@@ -628,6 +628,15 @@
Loading
628 628
        Ok(SegmentRawIter::new(segment, self.address.scan(segment)?, read_snapshot))
629 629
    }
630 630
631 +
    pub fn scan_snapshot_index(&self, segment_id: SegmentId, snapshot: SnapshotId) -> PRes<SegmentSnapshotRawIter> {
632 +
        let res = if let Some(r) = self.snapshots.scan(snapshot, segment_id)? {
633 +
            r
634 +
        } else {
635 +
            self.address.scan(segment_id)?
636 +
        };
637 +
        Ok(SegmentSnapshotRawIter::new(segment_id, res, snapshot))
638 +
    }
639 +
631 640
    pub fn scan_snapshot(&self, segment_id: SegmentId, snapshot: SnapshotId) -> PRes<SegmentSnapshotRawIter> {
632 641
        let res = self.snapshots.scan(snapshot, segment_id)?.unwrap();
633 642
        Ok(SegmentSnapshotRawIter::new(segment_id, res, snapshot))
@@ -745,7 +754,7 @@
Loading
745 754
        K: IndexType,
746 755
        V: IndexType,
747 756
    {
748 -
        let read_snapshot = self.snapshot()?;
757 +
        let read_snapshot = self.snapshots.read_snapshot()?;
749 758
        let r = self.get_snapshot(index_id, read_snapshot, k);
750 759
        release_snapshot(read_snapshot, &self.snapshots, &self.allocator, &self.journal)?;
751 760
        r
@@ -791,7 +800,7 @@
Loading
791 800
        V: IndexType,
792 801
        R: RangeBounds<K>,
793 802
    {
794 -
        let read_snapshot = self.snapshot()?;
803 +
        let read_snapshot = self.snapshots.read_snapshot()?;
795 804
        self.range_snapshot(index_id, read_snapshot, range, true)
796 805
    }
797 806
@@ -847,6 +856,7 @@
Loading
847 856
        release_snapshot(snapshot, &self.snapshots, &self.allocator, &self.journal)?;
848 857
        res
849 858
    }
859 +
850 860
    pub fn list_indexes_snapshot(&self, snapshot: SnapshotId) -> PRes<Vec<(String, IndexInfo)>> {
851 861
        let list = self.snapshots.list(snapshot)?;
852 862
        list.into_iter()

@@ -134,8 +134,7 @@
Loading
134 134
135 135
pub(crate) trait SegmentPageRead: PageOps {
136 136
    fn segment_read_entry(&mut self, segment_id: SegmentId, pos: u32) -> PRes<Option<(u64, u16)>>;
137 -
    fn segment_scan_entries(&mut self) -> PRes<(u64, Vec<u32>)>;
138 -
    fn segment_scan_all_entries(&mut self) -> PRes<(u64, Vec<(u32, bool)>)>;
137 +
    fn segment_scan_all_entries(&mut self) -> PRes<(u64, [(u32, bool); ADDRESS_PAGE_ENTRY_COUNT as usize])>;
139 138
    fn segment_first_available_pos(&mut self) -> PRes<u32>;
140 139
    fn get_next(&mut self) -> PRes<u64>;
141 140
    fn get_prev(&mut self) -> PRes<u64>;
@@ -173,33 +172,17 @@
Loading
173 172
        })
174 173
    }
175 174
176 -
    fn segment_scan_all_entries(&mut self) -> PRes<(u64, Vec<(u32, bool)>)> {
175 +
    fn segment_scan_all_entries(&mut self) -> PRes<(u64, [(u32, bool); ADDRESS_PAGE_ENTRY_COUNT as usize])> {
177 176
        let next_page = self.read_u64();
178 177
        let mut pos = SEGMENT_DATA_OFFSET;
179 -
        let mut recs = Vec::new();
178 +
        let mut recs = [(0, false); ADDRESS_PAGE_ENTRY_COUNT as usize];
179 +
        let mut iter = 0;
180 180
        loop {
181 181
            self.seek(pos + 8);
182 182
            let flag = self.read_u8();
183 -
            recs.push((pos, flag & FLAG_EXISTS == 1));
184 -
            pos += ADDRESS_ENTRY_SIZE;
185 -
            if pos > ADDRESS_PAGE_SIZE - ADDRESS_ENTRY_SIZE {
186 -
                break;
187 -
            }
188 -
        }
189 -
        Ok((next_page, recs))
190 -
    }
191 -
192 -
    fn segment_scan_entries(&mut self) -> PRes<(u64, Vec<u32>)> {
193 -
        let next_page = self.read_u64();
194 -
        let mut pos = SEGMENT_DATA_OFFSET;
195 -
        let mut recs = Vec::new();
196 -
        loop {
197 -
            self.seek(pos + 8);
198 -
            let flag = self.read_u8();
199 -
            if entry_exits(flag) {
200 -
                recs.push(pos);
201 -
            }
183 +
            recs[iter] = (pos, flag & FLAG_EXISTS == 1);
202 184
            pos += ADDRESS_ENTRY_SIZE;
185 +
            iter += 1;
203 186
            if pos > ADDRESS_PAGE_SIZE - ADDRESS_ENTRY_SIZE {
204 187
                break;
205 188
            }
@@ -617,7 +600,9 @@
Loading
617 600
pub struct SegmentPageIterator {
618 601
    cur_page: u64,
619 602
    next_page: u64,
620 -
    per_page_iterator: vec::IntoIter<u32>,
603 +
    per_page_iterator: [(u32, bool); ADDRESS_PAGE_ENTRY_COUNT as usize],
604 +
    iter_pos: usize,
605 +
    include_deleted: bool,
621 606
}
622 607
623 608
impl SegmentPageIterator {
@@ -625,58 +610,43 @@
Loading
625 610
        SegmentPageIterator {
626 611
            cur_page: first_page,
627 612
            next_page: first_page,
628 -
            per_page_iterator: Vec::new().into_iter(),
629 -
        }
630 -
    }
631 -
632 -
    pub fn next(&mut self, address: &Address) -> Option<RecRef> {
633 -
        // This loop is needed because some pages may be empty
634 -
        loop {
635 -
            let iter = self.per_page_iterator.next();
636 -
            if iter.is_none() && self.next_page != 0 {
637 -
                self.cur_page = self.next_page;
638 -
                if let Ok((next_page, elements)) = address.scan_page(self.cur_page) {
639 -
                    self.next_page = next_page;
640 -
                    self.per_page_iterator = elements.into_iter();
641 -
                    continue;
642 -
                }
643 -
            }
644 -
            break iter;
613 +
            per_page_iterator: [(0, false); ADDRESS_PAGE_ENTRY_COUNT as usize],
614 +
            iter_pos: 0,
615 +
            include_deleted: false,
645 616
        }
646 -
        .map(|pos| RecRef::new(self.cur_page, pos))
647 617
    }
648 -
}
649 -
650 -
pub struct SnapshotSegmentPageIterator {
651 -
    cur_page: u64,
652 -
    next_page: u64,
653 -
    per_page_iterator: vec::IntoIter<(u32, bool)>,
654 -
}
655 -
656 -
impl SnapshotSegmentPageIterator {
657 -
    pub fn new(first_page: u64) -> SnapshotSegmentPageIterator {
658 -
        SnapshotSegmentPageIterator {
618 +
    pub fn snapshot(first_page: u64) -> SegmentPageIterator {
619 +
        SegmentPageIterator {
659 620
            cur_page: first_page,
660 621
            next_page: first_page,
661 -
            per_page_iterator: Vec::new().into_iter(),
622 +
            per_page_iterator: [(0, false); ADDRESS_PAGE_ENTRY_COUNT as usize],
623 +
            iter_pos: 0,
624 +
            include_deleted: true,
662 625
        }
663 626
    }
664 627
665 628
    pub fn next(&mut self, address: &Address) -> Option<RecRef> {
666 629
        // This loop is needed because some pages may be empty
667 630
        loop {
668 -
            let iter = self.per_page_iterator.next();
669 -
            if iter.is_none() && self.next_page != 0 {
631 +
            if self.iter_pos < self.per_page_iterator.len() {
632 +
                let (pos, exists) = self.per_page_iterator[self.iter_pos];
633 +
                self.iter_pos += 1;
634 +
                if exists || self.include_deleted {
635 +
                    break Some(RecRef::new(self.cur_page, pos));
636 +
                } else {
637 +
                    continue;
638 +
                }
639 +
            } else if self.next_page != 0 {
670 640
                self.cur_page = self.next_page;
671 641
                if let Ok((next_page, elements)) = address.scan_page_all(self.cur_page) {
672 642
                    self.next_page = next_page;
673 -
                    self.per_page_iterator = elements.into_iter();
674 -
                    continue;
643 +
                    self.per_page_iterator = elements;
644 +
                    self.iter_pos = 0;
675 645
                }
646 +
            } else {
647 +
                break None;
676 648
            }
677 -
            break iter;
678 649
        }
679 -
        .map(|(pos, _exist)| RecRef::new(self.cur_page, pos))
680 650
    }
681 651
}
682 652

@@ -3,7 +3,7 @@
Loading
3 3
    error::PRes,
4 4
    id::{RecRef, SegmentId},
5 5
    journal::{Journal, JournalId},
6 -
    segment::SnapshotSegmentPageIterator,
6 +
    segment::SegmentPageIterator,
7 7
    transaction::FreedPage,
8 8
};
9 9
use std::{
@@ -312,13 +312,13 @@
Loading
312 312
        Ok(res)
313 313
    }
314 314
315 -
    pub fn scan(&self, snapshot_id: SnapshotId, segment_id: SegmentId) -> PRes<Option<SnapshotSegmentPageIterator>> {
315 +
    pub fn scan(&self, snapshot_id: SnapshotId, segment_id: SegmentId) -> PRes<Option<SegmentPageIterator>> {
316 316
        let mut lock = self.lock.lock()?;
317 317
        let res = if let Ok(index) = lock.search(snapshot_id) {
318 318
            if let Some(snap) = lock.active_snapshots.get_mut(index) {
319 319
                if let Some(segs) = &snap.segments {
320 320
                    if let Some(sd) = segs.get(&segment_id) {
321 -
                        Some(SnapshotSegmentPageIterator::new(sd.first_page))
321 +
                        Some(SegmentPageIterator::snapshot(sd.first_page))
322 322
                    } else {
323 323
                        None
324 324
                    }

@@ -386,7 +386,7 @@
Loading
386 386
387 387
    pub fn get_index(p: &PersyImpl, snapshot_id: SnapshotId, index_id: &IndexId) -> PRes<IndexConfig> {
388 388
        let segment_meta = index_id_to_segment_id_meta(index_id);
389 -
        p.scan_snapshot(segment_meta, snapshot_id)
389 +
        p.scan_snapshot_index(segment_meta, snapshot_id)
390 390
            .map_err(error_map)?
391 391
            .next(p)
392 392
            .map(|(_, content)| IndexConfig::deserialize(&mut Cursor::new(content)))

@@ -1,7 +1,7 @@
Loading
1 1
use crate::{
2 2
    id::SegmentId,
3 3
    persy::PersyImpl,
4 -
    segment::{SegmentPageIterator, SnapshotSegmentPageIterator},
4 +
    segment::SegmentPageIterator,
5 5
    snapshot::SnapshotId,
6 6
    transaction::{Transaction, TransactionInsertIterator},
7 7
    PRes, PersyId,
@@ -37,14 +37,14 @@
Loading
37 37
38 38
pub struct SegmentSnapshotRawIter {
39 39
    segment_id: SegmentId,
40 -
    iterator: SnapshotSegmentPageIterator,
40 +
    iterator: SegmentPageIterator,
41 41
    snapshot_id: SnapshotId,
42 42
}
43 43
44 44
impl SegmentSnapshotRawIter {
45 45
    pub fn new(
46 46
        segment_id: SegmentId,
47 -
        iterator: SnapshotSegmentPageIterator,
47 +
        iterator: SegmentPageIterator,
48 48
        snapshot_id: SnapshotId,
49 49
    ) -> SegmentSnapshotRawIter {
50 50
        SegmentSnapshotRawIter {

Click to load this diff.
Loading diff...

Learn more Showing 3 files with coverage changes found.

Changes in src/lib.rs
-2
Loading file...
Changes in src/persy.rs
-1
+1
Loading file...
Changes in src/snapshot.rs
-1
+1
Loading file...
Files Coverage
src -0.01% 92.77%
tests 98.56%
Project Totals (29 files) 93.81%
Loading