differential_dataflow/trace/implementations/
mod.rs1pub mod spine_fueled;
42
43pub mod merge_batcher;
44pub mod ord_neu;
45pub mod chunker;
46
47pub use self::chunker::ContainerChunker;
49pub use self::ord_neu::OrdValSpine as ValSpine;
50pub use self::ord_neu::OrdValBatcher as ValBatcher;
51pub use self::ord_neu::RcOrdValBuilder as ValBuilder;
52pub use self::ord_neu::OrdKeySpine as KeySpine;
53pub use self::ord_neu::OrdKeyBatcher as KeyBatcher;
54pub use self::ord_neu::RcOrdKeyBuilder as KeyBuilder;
55
56use std::convert::TryInto;
57
58use serde::{Deserialize, Serialize};
59use timely::container::{DrainContainer, PushInto};
60use timely::progress::Timestamp;
61
62use crate::lattice::Lattice;
63use crate::difference::Semigroup;
64
65pub trait Update {
67 type Key: Ord + Clone + 'static;
69 type Val: Ord + Clone + 'static;
71 type Time: Lattice + timely::progress::Timestamp;
73 type Diff: Ord + Semigroup + 'static;
75}
76
77impl<K,V,T,R> Update for ((K, V), T, R)
78where
79 K: Ord+Clone+'static,
80 V: Ord+Clone+'static,
81 T: Lattice+timely::progress::Timestamp,
82 R: Ord+Semigroup+'static,
83{
84 type Key = K;
85 type Val = V;
86 type Time = T;
87 type Diff = R;
88}
89
90pub trait Layout {
92 type KeyContainer: BatchContainer;
94 type ValContainer: BatchContainer;
96 type TimeContainer: BatchContainer<Owned: Lattice + timely::progress::Timestamp>;
98 type DiffContainer: BatchContainer<Owned: Semigroup + 'static>;
100 type OffsetContainer: for<'a> BatchContainer<ReadItem<'a> = usize>;
102}
103
104pub trait WithLayout {
106 type Layout: Layout;
108}
109
110
111impl<KC, VC, TC, DC, OC> Layout for (KC, VC, TC, DC, OC)
114where
115 KC: BatchContainer,
116 VC: BatchContainer,
117 TC: BatchContainer<Owned: Lattice + timely::progress::Timestamp>,
118 DC: BatchContainer<Owned: Semigroup>,
119 OC: for<'a> BatchContainer<ReadItem<'a> = usize>,
120{
121 type KeyContainer = KC;
122 type ValContainer = VC;
123 type TimeContainer = TC;
124 type DiffContainer = DC;
125 type OffsetContainer = OC;
126}
127
128pub mod layout {
132 use crate::trace::implementations::{BatchContainer, Layout};
133
134 pub type Key<L> = <<L as Layout>::KeyContainer as BatchContainer>::Owned;
136 pub type KeyRef<'a, L> = <<L as Layout>::KeyContainer as BatchContainer>::ReadItem<'a>;
138 pub type Val<L> = <<L as Layout>::ValContainer as BatchContainer>::Owned;
140 pub type ValRef<'a, L> = <<L as Layout>::ValContainer as BatchContainer>::ReadItem<'a>;
142 pub type Time<L> = <<L as Layout>::TimeContainer as BatchContainer>::Owned;
144 pub type TimeRef<'a, L> = <<L as Layout>::TimeContainer as BatchContainer>::ReadItem<'a>;
146 pub type Diff<L> = <<L as Layout>::DiffContainer as BatchContainer>::Owned;
148 pub type DiffRef<'a, L> = <<L as Layout>::DiffContainer as BatchContainer>::ReadItem<'a>;
150}
151
152pub struct Vector<U: Update> {
154 phantom: std::marker::PhantomData<U>,
155}
156
157impl<U: Update<Diff: Ord>> Layout for Vector<U> {
158 type KeyContainer = Vec<U::Key>;
159 type ValContainer = Vec<U::Val>;
160 type TimeContainer = Vec<U::Time>;
161 type DiffContainer = Vec<U::Diff>;
162 type OffsetContainer = OffsetList;
163}
164
165#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Serialize, Deserialize)]
167pub struct OffsetList {
168 pub zero_prefix: usize,
170 pub smol: Vec<u32>,
172 pub chonk: Vec<u64>,
174}
175
176impl std::fmt::Debug for OffsetList {
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 f.debug_list().entries(self.into_iter()).finish()
179 }
180}
181
182impl OffsetList {
183 pub fn with_capacity(cap: usize) -> Self {
185 Self {
186 zero_prefix: 0,
187 smol: Vec::with_capacity(cap),
188 chonk: Vec::new(),
189 }
190 }
191 pub fn push(&mut self, offset: usize) {
193 if self.smol.is_empty() && self.chonk.is_empty() && offset == 0 {
194 self.zero_prefix += 1;
195 }
196 else if self.chonk.is_empty() {
197 if let Ok(smol) = offset.try_into() {
198 self.smol.push(smol);
199 }
200 else {
201 self.chonk.push(offset.try_into().unwrap())
202 }
203 }
204 else {
205 self.chonk.push(offset.try_into().unwrap())
206 }
207 }
208 pub fn index(&self, index: usize) -> usize {
210 if index < self.zero_prefix {
211 0
212 }
213 else if index - self.zero_prefix < self.smol.len() {
214 self.smol[index - self.zero_prefix].try_into().unwrap()
215 }
216 else {
217 self.chonk[index - self.zero_prefix - self.smol.len()].try_into().unwrap()
218 }
219 }
220 pub fn len(&self) -> usize {
222 self.zero_prefix + self.smol.len() + self.chonk.len()
223 }
224}
225
226impl<'a> IntoIterator for &'a OffsetList {
227 type Item = usize;
228 type IntoIter = OffsetListIter<'a>;
229
230 fn into_iter(self) -> Self::IntoIter {
231 OffsetListIter {list: self, index: 0 }
232 }
233}
234
235pub struct OffsetListIter<'a> {
237 list: &'a OffsetList,
238 index: usize,
239}
240
241impl<'a> Iterator for OffsetListIter<'a> {
242 type Item = usize;
243
244 fn next(&mut self) -> Option<Self::Item> {
245 if self.index < self.list.len() {
246 let res = Some(self.list.index(self.index));
247 self.index += 1;
248 res
249 } else {
250 None
251 }
252 }
253}
254
255impl PushInto<usize> for OffsetList {
256 fn push_into(&mut self, item: usize) {
257 self.push(item);
258 }
259}
260
261impl BatchContainer for OffsetList {
262 type Owned = usize;
263 type ReadItem<'a> = usize;
264
265 #[inline(always)]
266 fn into_owned<'a>(item: Self::ReadItem<'a>) -> Self::Owned { item }
267 #[inline(always)]
268 fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b> { item }
269
270 fn push_ref(&mut self, item: Self::ReadItem<'_>) { self.push_into(item) }
271 fn push_own(&mut self, item: &Self::Owned) { self.push_into(*item) }
272
273 fn clear(&mut self) { self.zero_prefix = 0; self.smol.clear(); self.chonk.clear(); }
274
275 fn with_capacity(size: usize) -> Self {
276 Self::with_capacity(size)
277 }
278
279 fn merge_capacity(cont1: &Self, cont2: &Self) -> Self {
280 Self::with_capacity(cont1.len() + cont2.len())
281 }
282
283 fn index(&self, index: usize) -> Self::ReadItem<'_> {
284 self.index(index)
285 }
286
287 fn len(&self) -> usize {
288 self.len()
289 }
290}
291
292pub trait BuilderInput<K: BatchContainer, V: BatchContainer>: DrainContainer + Sized {
294 type Key<'a>: Ord;
296 type Val<'a>: Ord;
298 type Time;
300 type Diff;
302
303 fn into_parts<'a>(item: Self::Item<'a>) -> (Self::Key<'a>, Self::Val<'a>, Self::Time, Self::Diff);
305
306 fn key_eq(this: &Self::Key<'_>, other: K::ReadItem<'_>) -> bool;
308
309 fn val_eq(this: &Self::Val<'_>, other: V::ReadItem<'_>) -> bool;
311
312 fn key_val_upd_counts(chain: &[Self]) -> (usize, usize, usize);
314}
315
316impl<K,KBC,V,VBC,T,R> BuilderInput<KBC, VBC> for Vec<((K, V), T, R)>
317where
318 K: Ord + Clone + 'static,
319 KBC: for<'a> BatchContainer<ReadItem<'a>: PartialEq<&'a K>>,
320 V: Ord + Clone + 'static,
321 VBC: for<'a> BatchContainer<ReadItem<'a>: PartialEq<&'a V>>,
322 T: Timestamp + Lattice + 'static,
323 R: Ord + Semigroup + 'static,
324{
325 type Key<'a> = K;
326 type Val<'a> = V;
327 type Time = T;
328 type Diff = R;
329
330 fn into_parts<'a>(((key, val), time, diff): Self::Item<'a>) -> (Self::Key<'a>, Self::Val<'a>, Self::Time, Self::Diff) {
331 (key, val, time, diff)
332 }
333
334 fn key_eq(this: &K, other: KBC::ReadItem<'_>) -> bool {
335 KBC::reborrow(other) == this
336 }
337
338 fn val_eq(this: &V, other: VBC::ReadItem<'_>) -> bool {
339 VBC::reborrow(other) == this
340 }
341
342 fn key_val_upd_counts(chain: &[Self]) -> (usize, usize, usize) {
343 let mut keys = 0;
344 let mut vals = 0;
345 let mut upds = 0;
346 let mut prev_keyval = None;
347 for link in chain.iter() {
348 for ((key, val), _, _) in link.iter() {
349 if let Some((p_key, p_val)) = prev_keyval {
350 if p_key != key {
351 keys += 1;
352 vals += 1;
353 } else if p_val != val {
354 vals += 1;
355 }
356 } else {
357 keys += 1;
358 vals += 1;
359 }
360 upds += 1;
361 prev_keyval = Some((key, val));
362 }
363 }
364 (keys, vals, upds)
365 }
366}
367
368pub use self::containers::{BatchContainer, SliceContainer};
369
370pub mod containers {
372
373 use timely::container::PushInto;
374
375 pub trait BatchContainer: 'static {
377 type Owned: Clone + Ord;
379
380 type ReadItem<'a>: Copy + Ord;
382
383
384 #[must_use]
386 fn into_owned<'a>(item: Self::ReadItem<'a>) -> Self::Owned;
387 #[inline(always)]
389 fn clone_onto<'a>(item: Self::ReadItem<'a>, other: &mut Self::Owned) {
390 *other = Self::into_owned(item);
391 }
392
393 fn push_ref(&mut self, item: Self::ReadItem<'_>);
395 fn push_own(&mut self, item: &Self::Owned);
397
398 fn clear(&mut self);
400
401 fn with_capacity(size: usize) -> Self;
403 fn merge_capacity(cont1: &Self, cont2: &Self) -> Self;
405
406 fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b>;
408
409 fn index(&self, index: usize) -> Self::ReadItem<'_>;
411
412 fn get(&self, index: usize) -> Option<Self::ReadItem<'_>> {
414 if index < self.len() {
415 Some(self.index(index))
416 }
417 else { None }
418 }
419
420 fn len(&self) -> usize;
422 fn last(&self) -> Option<Self::ReadItem<'_>> {
424 if self.len() > 0 {
425 Some(self.index(self.len()-1))
426 }
427 else {
428 None
429 }
430 }
431 fn is_empty(&self) -> bool { self.len() == 0 }
433
434 fn advance<F: for<'a> Fn(Self::ReadItem<'a>)->bool>(&self, start: usize, end: usize, function: F) -> usize {
441
442 let small_limit = 8;
443
444 if end > start + small_limit && function(self.index(start + small_limit)) {
446
447 let mut index = small_limit + 1;
449 if start + index < end && function(self.index(start + index)) {
450
451 let mut step = 1;
453 while start + index + step < end && function(self.index(start + index + step)) {
454 index += step;
455 step <<= 1;
456 }
457
458 step >>= 1;
460 while step > 0 {
461 if start + index + step < end && function(self.index(start + index + step)) {
462 index += step;
463 }
464 step >>= 1;
465 }
466
467 index += 1;
468 }
469
470 index
471 }
472 else {
473 let limit = std::cmp::min(end, start + small_limit);
474 (start .. limit).filter(|x| function(self.index(*x))).count()
475 }
476 }
477 }
478
479 impl<T: Ord + Clone + 'static> BatchContainer for Vec<T> {
482 type Owned = T;
483 type ReadItem<'a> = &'a T;
484
485 #[inline(always)] fn into_owned<'a>(item: Self::ReadItem<'a>) -> Self::Owned { item.clone() }
486 #[inline(always)] fn clone_onto<'a>(item: Self::ReadItem<'a>, other: &mut Self::Owned) { other.clone_from(item); }
487
488 fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b> { item }
489
490 fn push_ref(&mut self, item: Self::ReadItem<'_>) { self.push_into(item) }
491 fn push_own(&mut self, item: &Self::Owned) { self.push_into(item.clone()) }
492
493 fn clear(&mut self) { self.clear() }
494
495 fn with_capacity(size: usize) -> Self {
496 Vec::with_capacity(size)
497 }
498 fn merge_capacity(cont1: &Self, cont2: &Self) -> Self {
499 Vec::with_capacity(cont1.len() + cont2.len())
500 }
501 fn index(&self, index: usize) -> Self::ReadItem<'_> {
502 &self[index]
503 }
504 fn get(&self, index: usize) -> Option<Self::ReadItem<'_>> {
505 <[T]>::get(self, index)
506 }
507 fn len(&self) -> usize {
508 self[..].len()
509 }
510 }
511
512 pub struct SliceContainer<B> {
514 offsets: Vec<usize>,
519 inner: Vec<B>,
521 }
522
523 impl<B: Ord + Clone + 'static> PushInto<&[B]> for SliceContainer<B> {
524 fn push_into(&mut self, item: &[B]) {
525 for x in item.iter() {
526 self.inner.push_into(x);
527 }
528 self.offsets.push(self.inner.len());
529 }
530 }
531
532 impl<B: Ord + Clone + 'static> PushInto<&Vec<B>> for SliceContainer<B> {
533 fn push_into(&mut self, item: &Vec<B>) {
534 self.push_into(&item[..]);
535 }
536 }
537
538 impl<B> BatchContainer for SliceContainer<B>
539 where
540 B: Ord + Clone + Sized + 'static,
541 {
542 type Owned = Vec<B>;
543 type ReadItem<'a> = &'a [B];
544
545 #[inline(always)] fn into_owned<'a>(item: Self::ReadItem<'a>) -> Self::Owned { item.to_vec() }
546 #[inline(always)] fn clone_onto<'a>(item: Self::ReadItem<'a>, other: &mut Self::Owned) { other.clone_from_slice(item); }
547
548 fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b> { item }
549
550 fn push_ref(&mut self, item: Self::ReadItem<'_>) { self.push_into(item) }
551 fn push_own(&mut self, item: &Self::Owned) { self.push_into(item) }
552
553 fn clear(&mut self) {
554 self.offsets.clear();
555 self.offsets.push(0);
556 self.inner.clear();
557 }
558
559 fn with_capacity(size: usize) -> Self {
560 let mut offsets = Vec::with_capacity(size + 1);
561 offsets.push(0);
562 Self {
563 offsets,
564 inner: Vec::with_capacity(size),
565 }
566 }
567 fn merge_capacity(cont1: &Self, cont2: &Self) -> Self {
568 let mut offsets = Vec::with_capacity(cont1.inner.len() + cont2.inner.len() + 1);
569 offsets.push(0);
570 Self {
571 offsets,
572 inner: Vec::with_capacity(cont1.inner.len() + cont2.inner.len()),
573 }
574 }
575 fn index(&self, index: usize) -> Self::ReadItem<'_> {
576 let lower = self.offsets[index];
577 let upper = self.offsets[index+1];
578 &self.inner[lower .. upper]
579 }
580 fn len(&self) -> usize {
581 self.offsets.len() - 1
582 }
583 }
584
585 impl<B> Default for SliceContainer<B> {
587 fn default() -> Self {
588 Self {
589 offsets: vec![0],
590 inner: Default::default(),
591 }
592 }
593 }
594}