pub mod cursor;
pub mod description;
pub mod implementations;
pub mod wrappers;
use timely::communication::message::RefOrMut;
use timely::logging::WorkerIdentifier;
use timely::logging_core::Logger;
use timely::progress::{Antichain, frontier::AntichainRef};
use timely::progress::Timestamp;
use crate::logging::DifferentialEvent;
use crate::trace::cursor::MyTrait;
pub use self::cursor::Cursor;
pub use self::description::Description;
pub type ExertionLogic = std::sync::Arc<dyn for<'a> Fn(Box<dyn Iterator<Item=(usize, usize, usize)>+'a>)->Option<usize>+Send+Sync>;
pub trait TraceReader {
type Key<'a>: Copy + Clone + MyTrait<'a, Owned = Self::KeyOwned>;
type KeyOwned: Ord + Clone;
type Val<'a>: Copy + Clone + MyTrait<'a, Owned = Self::ValOwned>;
type ValOwned: Ord + Clone;
type Time;
type Diff;
type Batch: for<'a> BatchReader<Key<'a> = Self::Key<'a>, KeyOwned = Self::KeyOwned, Val<'a> = Self::Val<'a>, ValOwned = Self::ValOwned, Time = Self::Time, Diff = Self::Diff>+Clone+'static;
type Storage;
type Cursor: for<'a> Cursor<Storage=Self::Storage, Key<'a> = Self::Key<'a>, KeyOwned = Self::KeyOwned, Val<'a> = Self::Val<'a>, ValOwned = Self::ValOwned, Time = Self::Time, Diff = Self::Diff>;
fn cursor(&mut self) -> (Self::Cursor, Self::Storage) {
if let Some(cursor) = self.cursor_through(Antichain::new().borrow()) {
cursor
}
else {
panic!("unable to acquire complete cursor for trace; is it closed?");
}
}
fn cursor_through(&mut self, upper: AntichainRef<Self::Time>) -> Option<(Self::Cursor, Self::Storage)>;
fn set_logical_compaction(&mut self, frontier: AntichainRef<Self::Time>);
#[deprecated(since = "0.11", note = "please use `set_logical_compaction`")]
fn advance_by(&mut self, frontier: AntichainRef<Self::Time>) {
self.set_logical_compaction(frontier);
}
fn get_logical_compaction(&mut self) -> AntichainRef<Self::Time>;
#[deprecated(since = "0.11", note = "please use `get_logical_compaction`")]
fn advance_frontier(&mut self) -> AntichainRef<Self::Time> {
self.get_logical_compaction()
}
fn set_physical_compaction(&mut self, frontier: AntichainRef<Self::Time>);
#[deprecated(since = "0.11", note = "please use `set_physical_compaction`")]
fn distinguish_since(&mut self, frontier: AntichainRef<Self::Time>) {
self.set_physical_compaction(frontier);
}
fn get_physical_compaction(&mut self) -> AntichainRef<Self::Time>;
#[deprecated(since = "0.11", note = "please use `get_physical_compaction`")]
fn distinguish_frontier(&mut self) -> AntichainRef<Self::Time> {
self.get_physical_compaction()
}
fn map_batches<F: FnMut(&Self::Batch)>(&self, f: F);
#[inline]
fn read_upper(&mut self, target: &mut Antichain<Self::Time>)
where
Self::Time: Timestamp,
{
target.clear();
target.insert(<Self::Time as timely::progress::Timestamp>::minimum());
self.map_batches(|batch| {
target.clone_from(batch.upper());
});
}
fn advance_upper(&mut self, upper: &mut Antichain<Self::Time>)
where
Self::Time: Timestamp,
{
self.map_batches(|batch| {
if batch.is_empty() && batch.lower() == upper {
upper.clone_from(batch.upper());
}
});
}
}
pub trait Trace : TraceReader
where <Self as TraceReader>::Batch: Batch {
type Batcher: Batcher<Time = Self::Time>;
type Builder: Builder<Item=<Self::Batcher as Batcher>::Item, Time=Self::Time, Output = Self::Batch>;
fn new(
info: ::timely::dataflow::operators::generic::OperatorInfo,
logging: Option<crate::logging::Logger>,
activator: Option<timely::scheduling::activate::Activator>,
) -> Self;
fn exert(&mut self);
fn set_exert_logic(&mut self, logic: ExertionLogic);
fn insert(&mut self, batch: Self::Batch);
fn close(&mut self);
}
pub trait BatchReader
where
Self: ::std::marker::Sized,
{
type Key<'a>: Copy + Clone + MyTrait<'a, Owned = Self::KeyOwned>;
type KeyOwned: Ord + Clone;
type Val<'a>: Copy + Clone + MyTrait<'a, Owned = Self::ValOwned>;
type ValOwned: Ord + Clone;
type Time: Timestamp;
type Diff;
type Cursor: for<'a> Cursor<Storage=Self, Key<'a> = Self::Key<'a>, KeyOwned = Self::KeyOwned, Val<'a> = Self::Val<'a>, ValOwned = Self::ValOwned, Time = Self::Time, Diff = Self::Diff>;
fn cursor(&self) -> Self::Cursor;
fn len(&self) -> usize;
fn is_empty(&self) -> bool { self.len() == 0 }
fn description(&self) -> &Description<Self::Time>;
fn lower(&self) -> &Antichain<Self::Time> { self.description().lower() }
fn upper(&self) -> &Antichain<Self::Time> { self.description().upper() }
}
pub trait Batch : BatchReader where Self: ::std::marker::Sized {
type Merger: Merger<Self>;
fn begin_merge(&self, other: &Self, compaction_frontier: AntichainRef<Self::Time>) -> Self::Merger {
Self::Merger::new(self, other, compaction_frontier)
}
}
pub trait Batcher {
type Item;
type Time: Timestamp;
fn new(logger: Option<Logger<DifferentialEvent, WorkerIdentifier>>, operator_id: usize) -> Self;
fn push_batch(&mut self, batch: RefOrMut<Vec<Self::Item>>);
fn seal<B: Builder<Item=Self::Item, Time=Self::Time>>(&mut self, upper: Antichain<Self::Time>) -> B::Output;
fn frontier(&mut self) -> timely::progress::frontier::AntichainRef<Self::Time>;
}
pub trait Builder: Sized {
type Item;
type Time: Timestamp;
type Output;
fn new() -> Self { Self::with_capacity(0, 0, 0) }
fn with_capacity(keys: usize, vals: usize, upds: usize) -> Self;
fn push(&mut self, element: Self::Item) {
self.copy(&element);
}
fn copy(&mut self, element: &Self::Item);
fn extend<I: Iterator<Item=Self::Item>>(&mut self, iter: I) {
for item in iter { self.push(item); }
}
fn done(self, lower: Antichain<Self::Time>, upper: Antichain<Self::Time>, since: Antichain<Self::Time>) -> Self::Output;
}
pub trait Merger<Output: Batch> {
fn new(source1: &Output, source2: &Output, compaction_frontier: AntichainRef<Output::Time>) -> Self;
fn work(&mut self, source1: &Output, source2: &Output, fuel: &mut isize);
fn done(self) -> Output;
}
pub mod rc_blanket_impls {
use std::rc::Rc;
use timely::progress::{Antichain, frontier::AntichainRef};
use super::{Batch, BatchReader, Builder, Merger, Cursor, Description};
impl<B: BatchReader> BatchReader for Rc<B> {
type Key<'a> = B::Key<'a>;
type KeyOwned = B::KeyOwned;
type Val<'a> = B::Val<'a>;
type ValOwned = B::ValOwned;
type Time = B::Time;
type Diff = B::Diff;
type Cursor = RcBatchCursor<B::Cursor>;
fn cursor(&self) -> Self::Cursor {
RcBatchCursor::new((**self).cursor())
}
fn len(&self) -> usize { (**self).len() }
fn description(&self) -> &Description<Self::Time> { (**self).description() }
}
pub struct RcBatchCursor<C> {
cursor: C,
}
impl<C> RcBatchCursor<C> {
fn new(cursor: C) -> Self {
RcBatchCursor {
cursor,
}
}
}
impl<C: Cursor> Cursor for RcBatchCursor<C> {
type Key<'a> = C::Key<'a>;
type KeyOwned = C::KeyOwned;
type Val<'a> = C::Val<'a>;
type ValOwned = C::ValOwned;
type Time = C::Time;
type Diff = C::Diff;
type Storage = Rc<C::Storage>;
#[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) }
#[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) }
#[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> Self::Key<'a> { self.cursor.key(storage) }
#[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> Self::Val<'a> { self.cursor.val(storage) }
#[inline]
fn map_times<L: FnMut(&Self::Time, &Self::Diff)>(&mut self, storage: &Self::Storage, logic: L) {
self.cursor.map_times(storage, logic)
}
#[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) }
#[inline] fn seek_key(&mut self, storage: &Self::Storage, key: Self::Key<'_>) { self.cursor.seek_key(storage, key) }
#[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) }
#[inline] fn seek_val(&mut self, storage: &Self::Storage, val: Self::Val<'_>) { self.cursor.seek_val(storage, val) }
#[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) }
#[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) }
}
impl<B: Batch> Batch for Rc<B> {
type Merger = RcMerger<B>;
}
pub struct RcBuilder<B: Builder> { builder: B }
impl<B: Builder> Builder for RcBuilder<B> {
type Item = B::Item;
type Time = B::Time;
type Output = Rc<B::Output>;
fn with_capacity(keys: usize, vals: usize, upds: usize) -> Self { RcBuilder { builder: B::with_capacity(keys, vals, upds) } }
fn push(&mut self, element: Self::Item) { self.builder.push(element) }
fn copy(&mut self, element: &Self::Item) { self.builder.copy(element) }
fn done(self, lower: Antichain<Self::Time>, upper: Antichain<Self::Time>, since: Antichain<Self::Time>) -> Rc<B::Output> { Rc::new(self.builder.done(lower, upper, since)) }
}
pub struct RcMerger<B:Batch> { merger: B::Merger }
impl<B:Batch> Merger<Rc<B>> for RcMerger<B> {
fn new(source1: &Rc<B>, source2: &Rc<B>, compaction_frontier: AntichainRef<B::Time>) -> Self { RcMerger { merger: B::begin_merge(source1, source2, compaction_frontier) } }
fn work(&mut self, source1: &Rc<B>, source2: &Rc<B>, fuel: &mut isize) { self.merger.work(source1, source2, fuel) }
fn done(self) -> Rc<B> { Rc::new(self.merger.done()) }
}
}
pub mod abomonated_blanket_impls {
use abomonation::{Abomonation, measure};
use abomonation::abomonated::Abomonated;
use timely::progress::{Antichain, frontier::AntichainRef};
use super::{Batch, BatchReader, Builder, Merger, Cursor, Description};
impl<B: BatchReader+Abomonation> BatchReader for Abomonated<B, Vec<u8>> {
type Key<'a> = B::Key<'a>;
type KeyOwned = B::KeyOwned;
type Val<'a> = B::Val<'a>;
type ValOwned = B::ValOwned;
type Time = B::Time;
type Diff = B::Diff;
type Cursor = AbomonatedBatchCursor<B::Cursor>;
fn cursor(&self) -> Self::Cursor {
AbomonatedBatchCursor::new((**self).cursor())
}
fn len(&self) -> usize { (**self).len() }
fn description(&self) -> &Description<Self::Time> { (**self).description() }
}
pub struct AbomonatedBatchCursor<C> {
cursor: C,
}
impl<C> AbomonatedBatchCursor<C> {
fn new(cursor: C) -> Self {
AbomonatedBatchCursor {
cursor,
}
}
}
impl<C: Cursor> Cursor for AbomonatedBatchCursor<C> where C::Storage: Abomonation {
type Key<'a> = C::Key<'a>;
type KeyOwned = C::KeyOwned;
type Val<'a> = C::Val<'a>;
type ValOwned = C::ValOwned;
type Time = C::Time;
type Diff = C::Diff;
type Storage = Abomonated<C::Storage, Vec<u8>>;
#[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) }
#[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) }
#[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> Self::Key<'a> { self.cursor.key(storage) }
#[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> Self::Val<'a> { self.cursor.val(storage) }
#[inline]
fn map_times<L: FnMut(&Self::Time, &Self::Diff)>(&mut self, storage: &Self::Storage, logic: L) {
self.cursor.map_times(storage, logic)
}
#[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) }
#[inline] fn seek_key(&mut self, storage: &Self::Storage, key: Self::Key<'_>) { self.cursor.seek_key(storage, key) }
#[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) }
#[inline] fn seek_val(&mut self, storage: &Self::Storage, val: Self::Val<'_>) { self.cursor.seek_val(storage, val) }
#[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) }
#[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) }
}
impl<B: Batch+Abomonation> Batch for Abomonated<B, Vec<u8>> {
type Merger = AbomonatedMerger<B>;
}
pub struct AbomonatedBuilder<B: Builder> { builder: B }
impl<B: Builder> Builder for AbomonatedBuilder<B>
where
B::Output: Abomonation,
{
type Item = B::Item;
type Time = B::Time;
type Output = Abomonated<B::Output, Vec<u8>>;
fn with_capacity(keys: usize, vals: usize, upds: usize) -> Self { AbomonatedBuilder { builder: B::with_capacity(keys, vals, upds) } }
fn push(&mut self, element: Self::Item) { self.builder.push(element) }
fn copy(&mut self, element: &Self::Item) { self.builder.copy(element) }
fn done(self, lower: Antichain<Self::Time>, upper: Antichain<Self::Time>, since: Antichain<Self::Time>) -> Self::Output {
let batch = self.builder.done(lower, upper, since);
let mut bytes = Vec::with_capacity(measure(&batch));
unsafe { abomonation::encode(&batch, &mut bytes).unwrap() };
unsafe { Abomonated::<B::Output,_>::new(bytes).unwrap() }
}
}
pub struct AbomonatedMerger<B:Batch> { merger: B::Merger }
impl<B:Batch+Abomonation> Merger<Abomonated<B,Vec<u8>>> for AbomonatedMerger<B> {
fn new(source1: &Abomonated<B,Vec<u8>>, source2: &Abomonated<B,Vec<u8>>, compaction_frontier: AntichainRef<B::Time>) -> Self {
AbomonatedMerger { merger: B::begin_merge(source1, source2, compaction_frontier) }
}
fn work(&mut self, source1: &Abomonated<B,Vec<u8>>, source2: &Abomonated<B,Vec<u8>>, fuel: &mut isize) {
self.merger.work(source1, source2, fuel)
}
fn done(self) -> Abomonated<B, Vec<u8>> {
let batch = self.merger.done();
let mut bytes = Vec::with_capacity(measure(&batch));
unsafe { abomonation::encode(&batch, &mut bytes).unwrap() };
unsafe { Abomonated::<B,_>::new(bytes).unwrap() }
}
}
}