No flags found
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
f977d25
... +0 ...
0e11be4
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 { |
Learn more Showing 3 files with coverage changes found.
src/lib.rs
src/persy.rs
src/snapshot.rs
0e11be4
3740a2d