1use columnar::{Columnar, Len};
11use timely::progress::frontier::{Antichain, AntichainRef};
12
13use super::layout::ColumnarUpdate as Update;
14use super::updates::UpdatesTyped;
15
16pub fn extract<U, I, FShip, FKept>(
22 merged: I,
23 upper: AntichainRef<U::Time>,
24 frontier: &mut Antichain<U::Time>,
25 mut ship: FShip,
26 mut kept: FKept,
27)
28where
29 U: Update,
30 U::Time: 'static,
31 I: IntoIterator<Item = UpdatesTyped<U>>,
32 FShip: FnMut(UpdatesTyped<U>),
33 FKept: FnMut(UpdatesTyped<U>),
34{
35 use columnar::{Container, ContainerOf, Index, Push};
36 use columnar::primitive::offsets::Strides;
37 use crate::columnar::updates::{Lists, retain_items};
38
39 let mut time_owned = U::Time::default();
41 let mut bitmap = Vec::new(); for chunk in merged {
43 bitmap.clear();
44 let view = chunk.view();
45 let times = view.times.values;
46 for idx in 0 .. times.len() {
47 Columnar::copy_from(&mut time_owned, times.get(idx));
48 if upper.less_equal(&time_owned) {
49 frontier.insert_ref(&time_owned);
50 bitmap.push(true);
51 }
52 else { bitmap.push(false); }
53 }
54 if bitmap.iter().all(|x| *x) { kept(chunk); }
55 else if bitmap.iter().all(|x| !*x) { ship(chunk); }
56 else {
57
58 let (times, temp) = retain_items::<ContainerOf<U::Time>>(view.times, &bitmap[..]);
59 let (vals, temp) = retain_items::<ContainerOf<U::Val>>(view.vals, &temp[..]);
60 let (keys, _temp) = retain_items::<ContainerOf<U::Key>>(view.keys, &temp[..]);
61 let d_borrow = view.diffs;
62 let mut diffs = <Lists::<ContainerOf<U::Diff>> as Container>::with_capacity_for([d_borrow].into_iter());
63 for (index, bit) in bitmap.iter().enumerate() {
64 if *bit { diffs.values.push(d_borrow.values.get(index)); }
65 }
66 diffs.bounds = Strides::new(1, times.values.len() as u64);
67 kept(UpdatesTyped {
68 keys,
69 vals,
70 times,
71 diffs,
72 });
73
74 for bit in bitmap.iter_mut() { *bit = !*bit; }
75
76 let (times, temp) = retain_items::<ContainerOf<U::Time>>(view.times, &bitmap[..]);
77 let (vals, temp) = retain_items::<ContainerOf<U::Val>>(view.vals, &temp[..]);
78 let (keys, _temp) = retain_items::<ContainerOf<U::Key>>(view.keys, &temp[..]);
79 let d_borrow = view.diffs;
80 let mut diffs = <Lists::<ContainerOf<U::Diff>> as Container>::with_capacity_for([d_borrow].into_iter());
81 for (index, bit) in bitmap.iter().enumerate() {
82 if *bit { diffs.values.push(d_borrow.values.get(index)); }
83 }
84 diffs.bounds = Strides::new(1, times.values.len() as u64);
85 ship(UpdatesTyped {
86 keys,
87 vals,
88 times,
89 diffs,
90 });
91 }
92 }
93}
94
95pub fn suffix_chunk<U: Update>(cursor: (usize, usize, usize), batch: &UpdatesTyped<U>) -> UpdatesTyped<U>
102where
103 U::Time: 'static,
104{
105 let (k, v, t) = cursor;
106 let view = batch.view();
107 let empty: UpdatesTyped<U> = Default::default();
108 let mut out = UpdatesTyped::<U>::default();
109 write_from_surveys(
110 batch,
111 &empty,
112 &[Report::This(0, 1)],
113 &[Report::This(k, view.keys.values.len())],
114 &[Report::This(v, view.vals.values.len())],
115 &[Report::This(t, view.times.values.len())],
116 &mut out,
117 );
118 out
119}
120
121#[inline(never)]
130pub fn merge_pair<U: Update>(
131 batch1: &mut Option<((usize, usize, usize), UpdatesTyped<U>)>,
132 batch2: &mut Option<((usize, usize, usize), UpdatesTyped<U>)>,
133) -> UpdatesTyped<U>
134where
135 U::Time: 'static,
136{
137 let ((k0_idx, v0_idx, t0_idx), updates0) = batch1.take().unwrap();
140 let ((k1_idx, v1_idx, t1_idx), updates1) = batch2.take().unwrap();
141
142 let view0 = updates0.view();
143 let view1 = updates1.view();
144 let keys0 = view0.keys;
145 let keys1 = view1.keys;
146 let vals0 = view0.vals;
147 let vals1 = view1.vals;
148 let times0 = view0.times;
149 let times1 = view1.times;
150
151 let mut key_survey = survey::<columnar::ContainerOf<U::Key>>(keys0, keys1, &[Report::Both(0,0)]);
153 let mut val_survey = survey::<columnar::ContainerOf<U::Val>>(vals0, vals1, &key_survey);
154 let mut time_survey = survey::<columnar::ContainerOf<U::Time>>(times0, times1, &val_survey);
155
156 if (k0_idx, v0_idx, t0_idx) != (0,0,0) {
170 let mut done = false; while !done { if let Report::This(l,u) = &mut key_survey[0] { if *u <= k0_idx { key_survey.remove(0); } else { *l = k0_idx; done = true; } } else { done = true; } }
171 let mut done = false; while !done { if let Report::This(l,u) = &mut val_survey[0] { if *u <= v0_idx { val_survey.remove(0); } else { *l = v0_idx; done = true; } } else { done = true; } }
172 let mut done = false; while !done { if let Report::This(l,u) = &mut time_survey[0] { if *u <= t0_idx { time_survey.remove(0); } else { *l = t0_idx; done = true; } } else { done = true; } }
173 }
174
175 if (k1_idx, v1_idx, t1_idx) != (0,0,0) {
176 let mut done = false; while !done { if let Report::That(l,u) = &mut key_survey[0] { if *u <= k1_idx { key_survey.remove(0); } else { *l = k1_idx; done = true; } } else { done = true; } }
177 let mut done = false; while !done { if let Report::That(l,u) = &mut val_survey[0] { if *u <= v1_idx { val_survey.remove(0); } else { *l = v1_idx; done = true; } } else { done = true; } }
178 let mut done = false; while !done { if let Report::That(l,u) = &mut time_survey[0] { if *u <= t1_idx { time_survey.remove(0); } else { *l = t1_idx; done = true; } } else { done = true; } }
179 }
180
181 let next_cursor = match time_survey.last().unwrap() {
189 Report::This(_,_) => {
190 let mut t = times0.values.len();
192 while let Some(Report::This(l,_)) = time_survey.last() { t = *l; time_survey.pop(); }
193 let mut v = vals0.values.len();
194 while let Some(Report::This(l,_)) = val_survey.last() { v = *l; val_survey.pop(); }
195 let mut k = keys0.values.len();
196 while let Some(Report::This(l,_)) = key_survey.last() { k = *l; key_survey.pop(); }
197 if v == times0.len() || times0.bounds.bounds(v).0 > t { v -= 1; }
199 if k == vals0.len() || vals0.bounds.bounds(k).0 > v { k -= 1; }
200 Some(Ok((k,v,t)))
201 }
202 Report::Both(_,_) => { None }
203 Report::That(_,_) => {
204 let mut t = times1.values.len();
206 while let Some(Report::That(l,_)) = time_survey.last() { t = *l; time_survey.pop(); }
207 let mut v = vals1.values.len();
208 while let Some(Report::That(l,_)) = val_survey.last() { v = *l; val_survey.pop(); }
209 let mut k = keys1.values.len();
210 while let Some(Report::That(l,_)) = key_survey.last() { k = *l; key_survey.pop(); }
211 if v == times1.len() || times1.bounds.bounds(v).0 > t { v -= 1; }
213 if k == vals1.len() || vals1.bounds.bounds(k).0 > v { k -= 1; }
214 Some(Err((k,v,t)))
215 }
216 };
217
218 let mut out_batch = UpdatesTyped::<U>::default();
220 write_from_surveys(&updates0, &updates1, &[Report::Both(0,0)], &key_survey, &val_survey, &time_survey, &mut out_batch);
222
223 match next_cursor {
224 Some(Ok(kvt)) => { *batch1 = Some((kvt, updates0)); }
225 Some(Err(kvt)) => {*batch2 = Some((kvt, updates1)); }
226 None => { }
227 }
228
229 out_batch
230}
231
232#[inline(never)]
237fn write_from_surveys<U: Update>(
238 updates0: &UpdatesTyped<U>,
239 updates1: &UpdatesTyped<U>,
240 root_survey: &[Report],
241 key_survey: &[Report],
242 val_survey: &[Report],
243 time_survey: &[Report],
244 output: &mut UpdatesTyped<U>,
245) {
246 let view0 = updates0.view();
247 let view1 = updates1.view();
248 write_layer(view0.keys, view1.keys, root_survey, key_survey, &mut output.keys);
249 write_layer(view0.vals, view1.vals, key_survey, val_survey, &mut output.vals);
250 write_layer(view0.times, view1.times, val_survey, time_survey, &mut output.times);
251 write_diffs::<U>(view0.diffs, view1.diffs, time_survey, &mut output.diffs);
252}
253
254#[inline(never)]
263pub fn survey<'a, C: columnar::Container<Ref<'a>: Ord>>(
264 lists0: <super::updates::Lists<C> as columnar::Borrow>::Borrowed<'a>,
265 lists1: <super::updates::Lists<C> as columnar::Borrow>::Borrowed<'a>,
266 reports: &[Report],
267) -> Vec<Report> {
268 use columnar::Index;
269 let mut output = Vec::with_capacity(reports.len()); for report in reports.iter() {
271 match report {
272 Report::This(lower0, upper0) => {
273 let (new_lower, _) = lists0.bounds.bounds(*lower0);
274 let (_, new_upper) = lists0.bounds.bounds(*upper0-1);
275 output.push(Report::This(new_lower, new_upper));
276 }
277 Report::Both(index0, index1) => {
278
279 let (mut lower0, upper0) = lists0.bounds.bounds(*index0);
281 let (mut lower1, upper1) = lists1.bounds.bounds(*index1);
282
283 while lower0 < upper0 && lower1 < upper1 {
285 let val0 = lists0.values.get(lower0);
286 let val1 = lists1.values.get(lower1);
287 match val0.cmp(&val1) {
288 std::cmp::Ordering::Less => {
289 let start = lower0;
290 lower0 += 1;
291 gallop(lists0.values, &mut lower0, upper0, |x| x < val1);
292 output.push(Report::This(start, lower0));
293 },
294 std::cmp::Ordering::Equal => {
295 output.push(Report::Both(lower0, lower1));
296 lower0 += 1;
297 lower1 += 1;
298 },
299 std::cmp::Ordering::Greater => {
300 let start = lower1;
301 lower1 += 1;
302 gallop(lists1.values, &mut lower1, upper1, |x| x < val0);
303 output.push(Report::That(start, lower1));
304 },
305 }
306 }
307 if lower0 < upper0 { output.push(Report::This(lower0, upper0)); }
308 if lower1 < upper1 { output.push(Report::That(lower1, upper1)); }
309
310 }
311 Report::That(lower1, upper1) => {
312 let (new_lower, _) = lists1.bounds.bounds(*lower1);
313 let (_, new_upper) = lists1.bounds.bounds(*upper1-1);
314 output.push(Report::That(new_lower, new_upper));
315 }
316 }
317 }
318
319 output
320}
321
322#[inline(never)]
333pub fn write_layer<'a, C: columnar::Container<Ref<'a>: Ord>>(
334 lists0: <super::updates::Lists<C> as columnar::Borrow>::Borrowed<'a>,
335 lists1: <super::updates::Lists<C> as columnar::Borrow>::Borrowed<'a>,
336 list_survey: &[Report],
337 item_survey: &[Report],
338 output: &mut super::updates::Lists<C>,
339) {
340 use columnar::{Container, Index};
341
342 let mut item_idx = 0;
343
344 for (pos, list_report) in list_survey.iter().enumerate() {
345 let is_first = pos == 0;
346 let is_last = pos == list_survey.len() - 1;
347 let may_be_pruned = is_first || is_last;
348
349 match list_report {
350 Report::This(lo, hi) => {
351 let Report::This(item_lo, item_hi) = item_survey[item_idx] else { unreachable!("Expected This in item survey for This list") };
352 item_idx += 1;
353 if may_be_pruned {
354 let base = output.values.len();
358 output.values.extend_from_self(lists0.values, item_lo..item_hi);
359 for i in *lo..*hi {
360 let (_, nat_hi) = lists0.bounds.bounds(i);
361 output.bounds.push((base + nat_hi.min(item_hi) - item_lo) as u64);
362 }
363 } else {
364 output.extend_from_self(lists0, *lo..*hi);
365 }
366 }
367 Report::That(lo, hi) => {
368 let Report::That(item_lo, item_hi) = item_survey[item_idx] else { unreachable!("Expected That in item survey for That list") };
369 item_idx += 1;
370 if may_be_pruned {
371 let base = output.values.len();
372 output.values.extend_from_self(lists1.values, item_lo..item_hi);
373 for i in *lo..*hi {
374 let (_, nat_hi) = lists1.bounds.bounds(i);
375 output.bounds.push((base + nat_hi.min(item_hi) - item_lo) as u64);
376 }
377 } else {
378 output.extend_from_self(lists1, *lo..*hi);
379 }
380 }
381 Report::Both(i0, i1) => {
382 let (mut c0, end0) = lists0.bounds.bounds(*i0);
384 let (mut c1, end1) = lists1.bounds.bounds(*i1);
385 while (c0 < end0 || c1 < end1) && item_idx < item_survey.len() {
386 match item_survey[item_idx] {
387 Report::This(lo, hi) => {
388 if lo >= end0 { break; }
389 output.values.extend_from_self(lists0.values, lo..hi);
390 c0 = hi;
391 }
392 Report::That(lo, hi) => {
393 if lo >= end1 { break; }
394 output.values.extend_from_self(lists1.values, lo..hi);
395 c1 = hi;
396 }
397 Report::Both(v0, v1) => {
398 if v0 >= end0 && v1 >= end1 { break; }
399 output.values.push(lists0.values.get(v0));
400 c0 = v0 + 1;
401 c1 = v1 + 1;
402 }
403 }
404 item_idx += 1;
405 }
406 output.bounds.push(output.values.len() as u64);
407 }
408 }
409 }
410}
411
412#[inline(never)]
422pub fn write_diffs<U: super::layout::ColumnarUpdate>(
423 diffs0: <super::updates::Lists<columnar::ContainerOf<U::Diff>> as columnar::Borrow>::Borrowed<'_>,
424 diffs1: <super::updates::Lists<columnar::ContainerOf<U::Diff>> as columnar::Borrow>::Borrowed<'_>,
425 time_survey: &[Report],
426 output: &mut super::updates::Lists<columnar::ContainerOf<U::Diff>>,
427) {
428 use columnar::{Columnar, Container, Index, Len, Push};
429 use crate::difference::{Semigroup, IsZero};
430
431 for report in time_survey.iter() {
432 match report {
433 Report::This(lo, hi) => { output.extend_from_self(diffs0, *lo..*hi); }
434 Report::That(lo, hi) => { output.extend_from_self(diffs1, *lo..*hi); }
435 Report::Both(t0, t1) => {
436 let (d0_lo, d0_hi) = diffs0.bounds.bounds(*t0);
438 let (d1_lo, d1_hi) = diffs1.bounds.bounds(*t1);
439 assert_eq!(d0_hi - d0_lo, 1, "Expected singleton diff list at t0={t0}");
440 assert_eq!(d1_hi - d1_lo, 1, "Expected singleton diff list at t1={t1}");
441 let mut diff: U::Diff = Columnar::into_owned(diffs0.values.get(d0_lo));
442 diff.plus_equals(&Columnar::into_owned(diffs1.values.get(d1_lo)));
443 if !diff.is_zero() { output.values.push(&diff); }
444 output.bounds.push(output.values.len() as u64);
445 }
446 }
447 }
448}
449
450#[inline(always)]
455pub(crate) fn gallop<C: columnar::Index>(input: C, lower: &mut usize, upper: usize, mut cmp: impl FnMut(<C as columnar::Index>::Ref) -> bool) {
456 if *lower < upper && cmp(input.get(*lower)) {
458 let mut step = 1;
459 while *lower + step < upper && cmp(input.get(*lower + step)) {
460 *lower += step;
461 step <<= 1;
462 }
463
464 step >>= 1;
465 while step > 0 {
466 if *lower + step < upper && cmp(input.get(*lower + step)) {
467 *lower += step;
468 }
469 step >>= 1;
470 }
471
472 *lower += 1;
473 }
474}
475
476#[derive(Copy, Clone, columnar::Columnar, Debug)]
482pub enum Report {
483 This(usize, usize),
485 That(usize, usize),
487 Both(usize, usize),
489}
490
491pub fn split_at<U: Update>(chunk: UpdatesTyped<U>, n: usize) -> (UpdatesTyped<U>, UpdatesTyped<U>)
495where
496 U::Time: 'static,
497{
498 use columnar::{Container, ContainerOf, Index, Push};
499 use columnar::primitive::offsets::Strides;
500 use crate::columnar::updates::{Lists, retain_items};
501
502 let total = chunk.len();
503 if n == 0 { return (UpdatesTyped::default(), chunk); }
504 if n >= total { return (chunk, UpdatesTyped::default()); }
505
506 let view = chunk.view();
507 let mut bitmap: Vec<bool> = (0..total).map(|i| i < n).collect();
508
509 let (times, temp) = retain_items::<ContainerOf<U::Time>>(view.times, &bitmap[..]);
511 let (vals, temp) = retain_items::<ContainerOf<U::Val>>(view.vals, &temp[..]);
512 let (keys, _temp) = retain_items::<ContainerOf<U::Key>>(view.keys, &temp[..]);
513 let d_borrow = view.diffs;
514 let mut diffs = <Lists::<ContainerOf<U::Diff>> as Container>::with_capacity_for([d_borrow].into_iter());
515 for (i, &bit) in bitmap.iter().enumerate() {
516 if bit { diffs.values.push(d_borrow.values.get(i)); }
517 }
518 diffs.bounds = Strides::new(1, times.values.len() as u64);
519 let first = UpdatesTyped { keys, vals, times, diffs };
520
521 for bit in bitmap.iter_mut() { *bit = !*bit; }
523 let (times, temp) = retain_items::<ContainerOf<U::Time>>(view.times, &bitmap[..]);
524 let (vals, temp) = retain_items::<ContainerOf<U::Val>>(view.vals, &temp[..]);
525 let (keys, _temp) = retain_items::<ContainerOf<U::Key>>(view.keys, &temp[..]);
526 let mut diffs = <Lists::<ContainerOf<U::Diff>> as Container>::with_capacity_for([d_borrow].into_iter());
527 for (i, &bit) in bitmap.iter().enumerate() {
528 if bit { diffs.values.push(d_borrow.values.get(i)); }
529 }
530 diffs.bounds = Strides::new(1, times.values.len() as u64);
531 let second = UpdatesTyped { keys, vals, times, diffs };
532
533 (first, second)
534}