sparse_vector/wand/
mmap.rs1use crate::mmap_index::{MmapPostingData, PostingEntry};
10
11use super::cursor::PostingCursor;
12use super::{DimId, Posting, RecordId, Weight};
13
14#[derive(Clone, Debug)]
17pub struct MmapCursor<'a> {
18 entries: &'a [PostingEntry],
19 pos: usize,
20}
21
22impl<'a> MmapCursor<'a> {
23 pub fn new(entries: &'a [PostingEntry]) -> Self {
26 Self { entries, pos: 0 }
27 }
28
29 pub fn open(data: &'a MmapPostingData, dim: DimId) -> Option<Self> {
32 let entries = data.entries(dim as usize);
33 (!entries.is_empty()).then(|| Self::new(entries))
34 }
35
36 #[inline]
37 fn fold(e: &PostingEntry) -> Posting {
38 Posting {
39 id: e.record_id,
40 weight: e.weight,
41 tail_max: e.weight.max(e.max_next_weight),
42 }
43 }
44}
45
46impl PostingCursor for MmapCursor<'_> {
47 #[inline]
48 fn peek(&self) -> Option<Posting> {
49 self.entries.get(self.pos).map(Self::fold)
50 }
51
52 #[inline]
53 fn advance(&mut self) {
54 if self.pos < self.entries.len() {
55 self.pos += 1;
56 }
57 }
58
59 fn seek(&mut self, target: RecordId) -> Option<Posting> {
60 let rest = &self.entries[self.pos.min(self.entries.len())..];
61 self.pos += rest.partition_point(|e| e.record_id < target);
62 self.peek()
63 }
64
65 #[inline]
66 fn remaining(&self) -> usize {
67 self.entries.len().saturating_sub(self.pos)
68 }
69
70 #[inline]
71 fn last_id(&self) -> Option<RecordId> {
72 self.entries.last().map(|e| e.record_id)
73 }
74
75 fn exhaust(&mut self) {
76 self.pos = self.entries.len();
77 }
78
79 fn drain_through(&mut self, hi: RecordId, mut visit: impl FnMut(RecordId, Weight)) {
80 let rest = &self.entries[self.pos.min(self.entries.len())..];
81 let mut taken = 0;
82 for e in rest {
83 if e.record_id > hi {
84 break;
85 }
86 visit(e.record_id, e.weight);
87 taken += 1;
88 }
89 self.pos += taken;
90 }
91}