differential_dataflow/trace/chunk/
cursor.rs1use crate::trace::Navigable;
12use crate::trace::cursor::Cursor;
13use crate::trace::implementations::BatchContainer;
14
15use super::{Chunk, ChunkBatch};
16
17pub trait NavigableChunk: Chunk + Navigable<Cursor: Cursor<Time = <Self as Chunk>::Time>> {
29 fn bounds(&self) -> (
31 (<Self::Cursor as Cursor>::Key<'_>, <Self::Cursor as Cursor>::Val<'_>, <Self::Cursor as Cursor>::TimeGat<'_>),
32 (<Self::Cursor as Cursor>::Key<'_>, <Self::Cursor as Cursor>::Val<'_>, <Self::Cursor as Cursor>::TimeGat<'_>),
33 );
34}
35
36type KeyCon<C> = <<C as Navigable>::Cursor as Cursor>::KeyContainer;
37type ValCon<C> = <<C as Navigable>::Cursor as Cursor>::ValContainer;
38
39impl<C: NavigableChunk> crate::trace::Navigable for ChunkBatch<C> {
40 type Cursor = ChunkBatchCursor<C>;
41 fn cursor(&self) -> Self::Cursor {
42 ChunkBatchCursor { key_chunk: 0, chunk: 0, inner: self.chunks.first().map(C::cursor) }
43 }
44}
45
46pub struct ChunkBatchCursor<C: NavigableChunk> {
61 key_chunk: usize,
63 chunk: usize,
65 inner: Option<C::Cursor>,
67}
68
69impl<C: NavigableChunk> ChunkBatchCursor<C> {
70 fn goto(&mut self, c: usize, storage: &ChunkBatch<C>) {
72 self.chunk = c;
73 self.inner = storage.chunks.get(c).map(C::cursor);
74 }
75
76 fn key_spills(s: &ChunkBatch<C>, c: usize, k: <C::Cursor as Cursor>::Key<'_>) -> bool {
82 <KeyCon<C> as BatchContainer>::reborrow(s.chunks[c].bounds().1.0) == <KeyCon<C> as BatchContainer>::reborrow(k)
83 && <KeyCon<C> as BatchContainer>::reborrow(s.chunks[c + 1].bounds().0.0) == <KeyCon<C> as BatchContainer>::reborrow(k)
84 }
85
86 fn val_spills(s: &ChunkBatch<C>, c: usize, k: <C::Cursor as Cursor>::Key<'_>, v: <C::Cursor as Cursor>::Val<'_>) -> bool {
88 Self::key_spills(s, c, k)
89 && <ValCon<C> as BatchContainer>::reborrow(s.chunks[c].bounds().1.1) == <ValCon<C> as BatchContainer>::reborrow(v)
90 && <ValCon<C> as BatchContainer>::reborrow(s.chunks[c + 1].bounds().0.1) == <ValCon<C> as BatchContainer>::reborrow(v)
91 }
92
93 fn locate_key(s: &ChunkBatch<C>, hint: usize, key: <C::Cursor as Cursor>::Key<'_>) -> usize {
99 let n = s.chunks.len();
100 let lt = |i: usize| <KeyCon<C> as BatchContainer>::reborrow(s.chunks[i].bounds().1.0)
102 .lt(&<KeyCon<C> as BatchContainer>::reborrow(key));
103 let hint = hint.min(n);
104 let lo = if hint == 0 || lt(hint - 1) { hint } else { 0 };
106 if lo >= n || !lt(lo) { return lo; }
107 let (mut prev, mut step) = (lo, 1usize);
109 while prev + step < n && lt(prev + step) { prev += step; step <<= 1; }
110 let (mut a, mut b) = (prev + 1, (prev + step).min(n));
111 while a < b { let m = a + (b - a) / 2; if lt(m) { a = m + 1; } else { b = m; } }
112 a
113 }
114}
115
116impl<C: NavigableChunk> Cursor for ChunkBatchCursor<C> {
117 type Storage = ChunkBatch<C>;
118
119 type KeyContainer = <C::Cursor as Cursor>::KeyContainer;
120 type Key<'a> = <C::Cursor as Cursor>::Key<'a>;
121 type ValContainer = <C::Cursor as Cursor>::ValContainer;
122 type Val<'a> = <C::Cursor as Cursor>::Val<'a>;
123 type ValOwn = <C::Cursor as Cursor>::ValOwn;
124 type TimeContainer = <C::Cursor as Cursor>::TimeContainer;
125 type TimeGat<'a> = <C::Cursor as Cursor>::TimeGat<'a>;
126 type Time = <C::Cursor as Cursor>::Time;
127 type DiffContainer = <C::Cursor as Cursor>::DiffContainer;
128 type DiffGat<'a> = <C::Cursor as Cursor>::DiffGat<'a>;
129 type Diff = <C::Cursor as Cursor>::Diff;
130
131 fn key_valid(&self, s: &Self::Storage) -> bool { self.chunk < s.chunks.len() && self.inner.as_ref().is_some_and(|i| i.key_valid(&s.chunks[self.chunk])) }
132 fn val_valid(&self, s: &Self::Storage) -> bool { self.chunk < s.chunks.len() && self.inner.as_ref().is_some_and(|i| i.val_valid(&s.chunks[self.chunk])) }
133 fn key<'a>(&self, s: &'a Self::Storage) -> Self::Key<'a> { self.inner.as_ref().unwrap().key(&s.chunks[self.chunk]) }
134 fn val<'a>(&self, s: &'a Self::Storage) -> Self::Val<'a> { self.inner.as_ref().unwrap().val(&s.chunks[self.chunk]) }
135 fn get_key<'a>(&self, s: &'a Self::Storage) -> Option<Self::Key<'a>> { if self.key_valid(s) { Some(self.key(s)) } else { None } }
136 fn get_val<'a>(&self, s: &'a Self::Storage) -> Option<Self::Val<'a>> { if self.val_valid(s) { Some(self.val(s)) } else { None } }
137
138 fn map_times<L: FnMut(Self::TimeGat<'_>, Self::DiffGat<'_>)>(&mut self, s: &Self::Storage, mut logic: L) {
139 if !self.val_valid(s) { return; }
140 let (k, v) = (self.key(s), self.val(s));
141 self.inner.as_mut().unwrap().map_times(&s.chunks[self.chunk], &mut logic);
142 let mut c = self.chunk;
144 while c + 1 < s.chunks.len() && Self::val_spills(s, c, k, v) {
145 c += 1;
146 s.chunks[c].cursor().map_times(&s.chunks[c], &mut logic);
147 }
148 }
149
150 fn step_key(&mut self, s: &Self::Storage) {
151 if !self.key_valid(s) { return; }
152 let n = s.chunks.len();
153 let k = self.key(s);
154 while self.chunk + 1 < n && Self::key_spills(s, self.chunk, k) {
156 self.goto(self.chunk + 1, s);
157 }
158 {
160 let inner = self.inner.as_mut().unwrap();
161 inner.seek_key(&s.chunks[self.chunk], k);
162 inner.step_key(&s.chunks[self.chunk]);
163 }
164 if !self.inner.as_ref().unwrap().key_valid(&s.chunks[self.chunk]) && self.chunk + 1 < n {
166 self.goto(self.chunk + 1, s);
167 }
168 self.key_chunk = self.chunk;
169 }
170
171 fn seek_key(&mut self, s: &Self::Storage, key: Self::Key<'_>) {
172 let n = s.chunks.len();
173 let lo = Self::locate_key(s, self.key_chunk, key);
176 self.goto(lo, s);
177 self.key_chunk = lo;
178 if lo < n { self.inner.as_mut().unwrap().seek_key(&s.chunks[lo], key); }
179 }
180
181 fn step_val(&mut self, s: &Self::Storage) {
182 if !self.val_valid(s) { return; }
183 let n = s.chunks.len();
184 let (k, v) = (self.key(s), self.val(s));
185 while self.chunk + 1 < n && Self::val_spills(s, self.chunk, k, v) {
187 self.goto(self.chunk + 1, s);
188 }
189 self.inner.as_mut().unwrap().step_val(&s.chunks[self.chunk]);
191 if !self.inner.as_ref().unwrap().val_valid(&s.chunks[self.chunk])
193 && self.chunk + 1 < n && Self::key_spills(s, self.chunk, k)
194 {
195 self.goto(self.chunk + 1, s);
196 self.inner.as_mut().unwrap().seek_key(&s.chunks[self.chunk], k);
197 }
198 }
199
200 fn seek_val(&mut self, s: &Self::Storage, val: Self::Val<'_>) {
201 if !self.key_valid(s) { return; }
202 let n = s.chunks.len();
203 let k = self.key(s);
204 loop {
205 self.inner.as_mut().unwrap().seek_val(&s.chunks[self.chunk], val);
206 if self.inner.as_ref().unwrap().val_valid(&s.chunks[self.chunk]) { return; }
207 if self.chunk + 1 < n && Self::key_spills(s, self.chunk, k) {
209 self.goto(self.chunk + 1, s);
210 self.inner.as_mut().unwrap().seek_key(&s.chunks[self.chunk], k);
211 } else {
212 return;
213 }
214 }
215 }
216
217 fn rewind_keys(&mut self, s: &Self::Storage) {
218 self.key_chunk = 0;
219 self.goto(0, s);
220 }
221
222 fn rewind_vals(&mut self, s: &Self::Storage) {
223 if !self.key_valid(s) { return; }
224 let k = self.key(s);
225 let kc = self.key_chunk;
226 self.goto(kc, s);
227 self.inner.as_mut().unwrap().seek_key(&s.chunks[kc], k);
228 }
229}