From 076e5dd40471efacdd2f4c7344bb561f7462fe31 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Thu, 28 Aug 2025 21:30:02 +0200 Subject: [PATCH 1/4] Adjust Differential to recent Timely changes Signed-off-by: Moritz Hoffmann --- Cargo.toml | 4 +- differential-dataflow/examples/columnar.rs | 71 +++++++++---------- differential-dataflow/src/collection.rs | 2 + differential-dataflow/src/consolidation.rs | 14 +++- differential-dataflow/src/containers.rs | 36 +++------- differential-dataflow/src/operators/join.rs | 6 +- differential-dataflow/src/operators/reduce.rs | 3 +- .../src/trace/implementations/chunker.rs | 11 +-- .../trace/implementations/merge_batcher.rs | 22 +++--- .../src/trace/implementations/mod.rs | 5 +- interactive/src/concrete.rs | 4 +- 11 files changed, 89 insertions(+), 89 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7da94260d..d184af962 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,9 @@ resolver = "2" [workspace.dependencies] differential-dataflow = { path = "differential-dataflow", default-features = false, version = "0.16.2" } -timely = { version = "0.23", default-features = false } +#timely = { version = "0.23", default-features = false } columnar = { version = "0.10", default-features = false } -#timely = { path = "../timely-dataflow/timely/", default-features = false } +timely = { git = "https://github.com/TimelyDataflow/timely-dataflow", default-features = false } [profile.release] opt-level = 3 diff --git a/differential-dataflow/examples/columnar.rs b/differential-dataflow/examples/columnar.rs index b5af06ef2..e21e61032 100644 --- a/differential-dataflow/examples/columnar.rs +++ b/differential-dataflow/examples/columnar.rs @@ -1,11 +1,9 @@ //! Wordcount based on `columnar`. -use { - timely::container::{Container, CapacityContainerBuilder}, - timely::dataflow::channels::pact::ExchangeCore, - timely::dataflow::InputHandleCore, - timely::dataflow::ProbeHandle, -}; +use timely::container::{CapacityContainerBuilder, PushInto}; +use timely::dataflow::channels::pact::ExchangeCore; +use timely::dataflow::InputHandleCore; +use timely::dataflow::ProbeHandle; use differential_dataflow::trace::implementations::ord_neu::ColKeySpine; @@ -65,7 +63,7 @@ fn main() { while i < size { let val = (counter + i) % keys; write!(buffer, "{:?}", val).unwrap(); - container.push(((&buffer, ()), time, 1)); + container.push_into(((&buffer, ()), time, 1)); buffer.clear(); i += worker.peers(); } @@ -88,7 +86,7 @@ fn main() { while i < size { let val = (queries + i) % keys; write!(buffer, "{:?}", val).unwrap(); - container.push(((&buffer, ()), time, 1)); + container.push_into(((&buffer, ()), time, 1)); buffer.clear(); i += worker.peers(); } @@ -169,26 +167,29 @@ mod container { pub fn get(&self, index: usize) -> columnar::Ref<'_, C> { self.borrow().get(index) } - } - - use timely::Container; - impl Container for Column { - fn len(&self) -> usize { - match self { - Column::Typed(t) => t.len(), - Column::Bytes(b) => as FromBytes>::from_bytes(&mut Indexed::decode(bytemuck::cast_slice(b))).len(), - Column::Align(a) => as FromBytes>::from_bytes(&mut Indexed::decode(a)).len(), - } - } // This sets the `Bytes` variant to be an empty `Typed` variant, appropriate for pushing into. - fn clear(&mut self) { + pub(crate) fn clear(&mut self) { match self { Column::Typed(t) => t.clear(), Column::Bytes(_) => *self = Column::Typed(Default::default()), Column::Align(_) => *self = Column::Typed(Default::default()), } } + #[inline] + pub fn len(&self) -> usize { + match self { + Column::Typed(t) => t.len(), + Column::Bytes(b) => as FromBytes>::from_bytes(&mut Indexed::decode(bytemuck::cast_slice(b))).len(), + Column::Align(a) => as FromBytes>::from_bytes(&mut Indexed::decode(a)).len(), + } + } + } + + impl timely::Accountable for Column { + #[inline] fn record_count(&self) -> i64 { self.len() as i64 } + } + impl timely::container::IterContainer for Column { type ItemRef<'a> = columnar::Ref<'a, C>; type Iter<'a> = IterOwn>; fn iter<'a>(&'a self) -> Self::Iter<'a> { @@ -198,7 +199,9 @@ mod container { Column::Align(a) => as FromBytes>::from_bytes(&mut Indexed::decode(a)).into_index_iter(), } } + } + impl timely::container::DrainContainer for Column { type Item<'a> = columnar::Ref<'a, C>; type DrainIter<'a> = IterOwn>; fn drain<'a>(&'a mut self) -> Self::DrainIter<'a> { @@ -366,7 +369,7 @@ pub mod batcher { use std::collections::VecDeque; use columnar::Columnar; use timely::Container; - use timely::container::{ContainerBuilder, PushInto}; + use timely::container::{ContainerBuilder, DrainContainer, PushInto, SizableContainer}; use differential_dataflow::difference::Semigroup; use crate::Column; @@ -414,9 +417,11 @@ pub mod batcher { for<'b> columnar::Ref<'b, T>: Ord, R: for<'b> Columnar + for<'b> Semigroup>, for<'b> columnar::Ref<'b, R>: Ord, - C2: Container + for<'b, 'c> PushInto<(columnar::Ref<'b, D>, columnar::Ref<'b, T>, &'c R)>, + C2: Container + SizableContainer + for<'b, 'c> PushInto<(columnar::Ref<'b, D>, columnar::Ref<'b, T>, &'c R)>, { fn push_into(&mut self, container: &'a mut Column<(D, T, R)>) { + let mut target: C2 = Default::default(); + target.ensure_capacity(&mut Some(std::mem::take(&mut self.empty))); // Scoped to let borrow through `permutation` drop. { @@ -426,7 +431,6 @@ pub mod batcher { permutation.extend(container.drain()); permutation.sort(); - self.empty.clear(); // Iterate over the data, accumulating diffs for like keys. let mut iter = permutation.drain(..); if let Some((data, time, diff)) = iter.next() { @@ -442,7 +446,7 @@ pub mod batcher { else { if !prev_diff.is_zero() { let tuple = (prev_data, prev_time, &prev_diff); - self.empty.push_into(tuple); + target.push_into(tuple); } prev_data = data; prev_time = time; @@ -452,13 +456,13 @@ pub mod batcher { if !prev_diff.is_zero() { let tuple = (prev_data, prev_time, &prev_diff); - self.empty.push_into(tuple); + target.push_into(tuple); } } } - if !self.empty.is_empty() { - self.ready.push_back(std::mem::take(&mut self.empty)); + if !target.is_empty() { + self.ready.push_back(target); } } } @@ -468,7 +472,7 @@ pub mod batcher { use timely::progress::{Antichain, frontier::AntichainRef}; use columnar::Columnar; - + use timely::container::PushInto; use crate::container::Column; use differential_dataflow::difference::Semigroup; @@ -502,7 +506,6 @@ pub mod batcher { } } fn is_empty(&self) -> bool { - use timely::Container; self.head == self.list.len() } fn cmp_heads(&self, other: &Self) -> std::cmp::Ordering { @@ -551,8 +554,7 @@ pub mod batcher { let stash2: R = R::into_owned(diff2); stash.plus_equals(&stash2); if !stash.is_zero() { - use timely::Container; - self.push((data, time, &*stash)); + self.push_into((data, time, &*stash)); } } fn account(&self) -> (usize, usize, usize, usize) { @@ -568,6 +570,7 @@ pub mod batcher { // self.heap_size(cb); // (self.len(), size, capacity, allocations) } + #[inline] fn clear(&mut self) { self.clear() } } } @@ -578,7 +581,7 @@ use dd_builder::ColKeyBuilder; pub mod dd_builder { use columnar::Columnar; - + use timely::container::DrainContainer; use differential_dataflow::trace::Builder; use differential_dataflow::trace::Description; use differential_dataflow::trace::implementations::Layout; @@ -630,8 +633,6 @@ pub mod dd_builder { #[inline] fn push(&mut self, chunk: &mut Self::Input) { - use timely::Container; - // NB: Maintaining owned key and val across iterations to track the "last", which we clone into, // is somewhat appealing from an ease point of view. Might still allocate, do work we don't need, // but avoids e.g. calls into `last()` and breaks horrid trait requirements. @@ -737,8 +738,6 @@ pub mod dd_builder { #[inline] fn push(&mut self, chunk: &mut Self::Input) { - use timely::Container; - // NB: Maintaining owned key and val across iterations to track the "last", which we clone into, // is somewhat appealing from an ease point of view. Might still allocate, do work we don't need, // but avoids e.g. calls into `last()` and breaks horrid trait requirements. diff --git a/differential-dataflow/src/collection.rs b/differential-dataflow/src/collection.rs index e901fc747..25ceb88b7 100644 --- a/differential-dataflow/src/collection.rs +++ b/differential-dataflow/src/collection.rs @@ -11,6 +11,7 @@ use std::hash::Hash; use timely::Container; +use timely::container::IterContainer; use timely::Data; use timely::progress::Timestamp; use timely::order::Product; @@ -155,6 +156,7 @@ impl Collection { pub fn inspect_container(&self, func: F) -> Self where F: FnMut(Result<(&G::Timestamp, &C), &[G::Timestamp]>)+'static, + C: IterContainer, { self.inner .inspect_container(func) diff --git a/differential-dataflow/src/consolidation.rs b/differential-dataflow/src/consolidation.rs index 7ed931ee5..0d5271b9e 100644 --- a/differential-dataflow/src/consolidation.rs +++ b/differential-dataflow/src/consolidation.rs @@ -12,8 +12,7 @@ use std::cmp::Ordering; use std::collections::VecDeque; -use timely::Container; -use timely::container::{ContainerBuilder, PushInto}; +use timely::container::{ContainerBuilder, DrainContainer, PushInto}; use crate::Data; use crate::difference::{IsZero, Semigroup}; @@ -239,7 +238,7 @@ where /// items. Consolidation accumulates the diffs per key. /// /// The trait requires `Container` to have access to its `Item` GAT. -pub trait ConsolidateLayout: Container { +pub trait ConsolidateLayout: DrainContainer { /// Key portion of data, essentially everything minus the diff type Key<'a>: Eq where Self: 'a; @@ -269,6 +268,12 @@ pub trait ConsolidateLayout: Container { /// Compare two items by key to sort containers. fn cmp(item1: &Self::Item<'_>, item2: &Self::Item<'_>) -> Ordering; + /// Returns the number of items in the container. + fn len(&self) -> usize; + + /// Clear the container. Afterwards, `len()` should return 0. + fn clear(&mut self); + /// Consolidate the supplied container. fn consolidate_into(&mut self, target: &mut Self) { // Sort input data @@ -329,6 +334,9 @@ where self.push((data, time, diff)); } + #[inline] fn len(&self) -> usize { Vec::len(self) } + #[inline] fn clear(&mut self) { Vec::clear(self) } + /// Consolidate the supplied container. fn consolidate_into(&mut self, target: &mut Self) { consolidate_updates(self); diff --git a/differential-dataflow/src/containers.rs b/differential-dataflow/src/containers.rs index 9d974104c..b8312a0ed 100644 --- a/differential-dataflow/src/containers.rs +++ b/differential-dataflow/src/containers.rs @@ -271,41 +271,27 @@ mod container { use std::ops::Deref; use columnation::Columnation; - use timely::Container; - use timely::container::SizableContainer; use crate::containers::TimelyStack; - impl Container for TimelyStack { + impl timely::container::Accountable for TimelyStack { + #[inline] fn record_count(&self) -> i64 { i64::try_from(self.local.len()).unwrap() } + #[inline] fn is_empty(&self) -> bool { self.local.is_empty() } + } + impl timely::container::IterContainer for TimelyStack { type ItemRef<'a> = &'a T where Self: 'a; - type Item<'a> = &'a T where Self: 'a; - - fn len(&self) -> usize { - self.local.len() - } - - fn is_empty(&self) -> bool { - self.local.is_empty() - } - - fn clear(&mut self) { - TimelyStack::clear(self) - } - type Iter<'a> = std::slice::Iter<'a, T> where Self: 'a; - - fn iter(&self) -> Self::Iter<'_> { - self.deref().iter() - } - + #[inline] fn iter(&self) -> Self::Iter<'_> { self.deref().iter() } + } + impl timely::container::DrainContainer for TimelyStack { + type Item<'a> = &'a T where Self: 'a; type DrainIter<'a> = std::slice::Iter<'a, T> where Self: 'a; - - fn drain(&mut self) -> Self::DrainIter<'_> { + #[inline] fn drain(&mut self) -> Self::DrainIter<'_> { (*self).iter() } } - impl SizableContainer for TimelyStack { + impl timely::container::SizableContainer for TimelyStack { fn at_capacity(&self) -> bool { self.len() == self.capacity() } diff --git a/differential-dataflow/src/operators/join.rs b/differential-dataflow/src/operators/join.rs index 93be1c13a..17d590d9f 100644 --- a/differential-dataflow/src/operators/join.rs +++ b/differential-dataflow/src/operators/join.rs @@ -4,8 +4,8 @@ //! the multiplication distributes over addition. That is, we will repeatedly evaluate (a + b) * c as (a * c) //! + (b * c), and if this is not equal to the former term, little is known about the actual output. use std::cmp::Ordering; -use timely::Container; +use timely::Accountable; use timely::container::{ContainerBuilder, PushInto}; use timely::order::PartialOrder; use timely::progress::Timestamp; @@ -324,14 +324,14 @@ impl ContainerBuilder for EffortBuilder { #[inline] fn extract(&mut self) -> Option<&mut Self::Container> { let extracted = self.1.extract(); - self.0.replace(self.0.take() + extracted.as_ref().map_or(0, |e| e.len())); + self.0.replace(self.0.take() + extracted.as_ref().map_or(0, |e| e.record_count() as usize)); extracted } #[inline] fn finish(&mut self) -> Option<&mut Self::Container> { let finished = self.1.finish(); - self.0.replace(self.0.take() + finished.as_ref().map_or(0, |e| e.len())); + self.0.replace(self.0.take() + finished.as_ref().map_or(0, |e| e.record_count() as usize)); finished } } diff --git a/differential-dataflow/src/operators/reduce.rs b/differential-dataflow/src/operators/reduce.rs index 8d1880d87..502b19690 100644 --- a/differential-dataflow/src/operators/reduce.rs +++ b/differential-dataflow/src/operators/reduce.rs @@ -533,7 +533,8 @@ where for (val, time, diff) in buffers[index].1.drain(..) { buffer.push_into(((T1::owned_key(key), val), time, diff)); builders[index].push(&mut buffer); - buffer.clear(); + // TODO: Clear! + // buffer.clear(); } } } diff --git a/differential-dataflow/src/trace/implementations/chunker.rs b/differential-dataflow/src/trace/implementations/chunker.rs index c47bd95cd..71d7aeb41 100644 --- a/differential-dataflow/src/trace/implementations/chunker.rs +++ b/differential-dataflow/src/trace/implementations/chunker.rs @@ -4,7 +4,7 @@ use std::collections::VecDeque; use columnation::Columnation; use timely::Container; -use timely::container::{ContainerBuilder, PushInto, SizableContainer}; +use timely::container::{ContainerBuilder, DrainContainer, PushInto, SizableContainer}; use crate::containers::TimelyStack; use crate::consolidation::{consolidate_updates, ConsolidateLayout}; @@ -254,8 +254,9 @@ impl Default for ContainerChunker { impl<'a, Input, Output> PushInto<&'a mut Input> for ContainerChunker where - Input: Container, - Output: SizableContainer + Input: DrainContainer, + Output: Default + + SizableContainer + ConsolidateLayout + PushInto>, { @@ -263,7 +264,7 @@ where self.pending.ensure_capacity(&mut None); for item in container.drain() { - self.pending.push(item); + self.pending.push_into(item); if self.pending.at_capacity() { let starting_len = self.pending.len(); self.pending.consolidate_into(&mut self.empty); @@ -282,7 +283,7 @@ where impl ContainerBuilder for ContainerChunker where - Output: SizableContainer + ConsolidateLayout + Clone + 'static, + Output: SizableContainer + ConsolidateLayout + Container, { type Container = Output; diff --git a/differential-dataflow/src/trace/implementations/merge_batcher.rs b/differential-dataflow/src/trace/implementations/merge_batcher.rs index 90a74f662..37c247c86 100644 --- a/differential-dataflow/src/trace/implementations/merge_batcher.rs +++ b/differential-dataflow/src/trace/implementations/merge_batcher.rs @@ -14,7 +14,6 @@ use std::marker::PhantomData; use timely::progress::frontier::AntichainRef; use timely::progress::{frontier::Antichain, Timestamp}; -use timely::Container; use timely::container::{ContainerBuilder, PushInto}; use crate::logging::{BatcherEvent, Logger}; @@ -200,7 +199,7 @@ impl Drop for MergeBatcher { /// A trait to describe interesting moments in a merge batcher. pub trait Merger: Default { /// The internal representation of chunks of data. - type Chunk: Container; + type Chunk: Default; /// The type of time in frontiers to extract updates. type Time; /// Merge chains into an output chain. @@ -238,14 +237,14 @@ pub mod container { use std::cmp::Ordering; use std::marker::PhantomData; - use timely::{Container, container::{PushInto, SizableContainer}}; + use timely::container::{PushInto, SizableContainer}; use timely::progress::frontier::{Antichain, AntichainRef}; - use timely::{Data, PartialOrder}; - + use timely::{Accountable, Data, PartialOrder}; + use timely::container::DrainContainer; use crate::trace::implementations::merge_batcher::Merger; /// An abstraction for a container that can be iterated over, and conclude by returning itself. - pub trait ContainerQueue { + pub trait ContainerQueue { /// Returns either the next item in the container, or the container itself. fn next_or_alloc(&mut self) -> Result, C>; /// Indicates whether `next_or_alloc` will return `Ok`, and whether `peek` will return `Some`. @@ -257,7 +256,7 @@ pub mod container { } /// Behavior to dissect items of chunks in the merge batcher - pub trait MergerChunk : SizableContainer { + pub trait MergerChunk : Accountable + DrainContainer + SizableContainer + Default { /// An owned time type. /// /// This type is provided so that users can maintain antichains of something, in order to track @@ -284,8 +283,11 @@ pub mod container { // TODO: Find a more universal home for this: `Container`? fn account(&self) -> (usize, usize, usize, usize) { let (size, capacity, allocations) = (0, 0, 0); - (self.len(), size, capacity, allocations) + (usize::try_from(self.record_count()).unwrap(), size, capacity, allocations) } + + /// Clear the chunk, to be reused. + fn clear(&mut self); } /// A merger for arbitrary containers. @@ -323,7 +325,7 @@ pub mod container { impl Merger for ContainerMerger where - for<'a> MC: MergerChunk + Clone + PushInto<::Item<'a>> + 'static, + for<'a> MC: MergerChunk + Clone + Default + PushInto<::Item<'a>> + 'static, CQ: ContainerQueue, { type Time = MC::TimeOwned; @@ -510,6 +512,7 @@ pub mod container { let (size, capacity, allocations) = (0, 0, 0); (self.len(), size, capacity, allocations) } + #[inline] fn clear(&mut self) { Vec::clear(self) } } } @@ -597,6 +600,7 @@ pub mod container { self.heap_size(cb); (self.len(), size, capacity, allocations) } + #[inline] fn clear(&mut self) { TimelyStack::clear(self) } } } } diff --git a/differential-dataflow/src/trace/implementations/mod.rs b/differential-dataflow/src/trace/implementations/mod.rs index c9c15206a..ea393701d 100644 --- a/differential-dataflow/src/trace/implementations/mod.rs +++ b/differential-dataflow/src/trace/implementations/mod.rs @@ -58,8 +58,7 @@ use std::convert::TryInto; use columnation::Columnation; use serde::{Deserialize, Serialize}; -use timely::Container; -use timely::container::PushInto; +use timely::container::{DrainContainer, PushInto}; use timely::progress::Timestamp; use crate::containers::TimelyStack; @@ -378,7 +377,7 @@ impl BatchContainer for OffsetList { } /// Behavior to split an update into principal components. -pub trait BuilderInput: Container { +pub trait BuilderInput: DrainContainer + Sized { /// Key portion type Key<'a>: Ord; /// Value portion diff --git a/interactive/src/concrete.rs b/interactive/src/concrete.rs index e2ceb6478..5d3c8e9ed 100644 --- a/interactive/src/concrete.rs +++ b/interactive/src/concrete.rs @@ -86,7 +86,7 @@ impl VectorFrom for Value { x.source.into(), x.target.into(), x.seq_no.into(), - x.length.into(), + usize::try_from(x.record_count).unwrap().into(), ] }, TimelyEvent::Shutdown(x) => { vec![x.id.into()] }, @@ -126,4 +126,4 @@ impl VectorFrom for Value { _ => { vec![] }, } } -} \ No newline at end of file +} From ec0577766bdc2f2f316d46acea50b6be3a83cde2 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Fri, 29 Aug 2025 12:47:48 +0200 Subject: [PATCH 2/4] Cleanup, use MergerChunk to clear in reduce Signed-off-by: Moritz Hoffmann --- differential-dataflow/examples/columnar.rs | 2 +- differential-dataflow/src/collection.rs | 4 ++-- .../src/operators/arrange/arrangement.rs | 7 ++++--- differential-dataflow/src/operators/iterate.rs | 12 ++++++------ differential-dataflow/src/operators/join.rs | 2 +- differential-dataflow/src/operators/reduce.rs | 8 +++----- .../src/trace/implementations/merge_batcher.rs | 4 ++-- 7 files changed, 19 insertions(+), 20 deletions(-) diff --git a/differential-dataflow/examples/columnar.rs b/differential-dataflow/examples/columnar.rs index e21e61032..ac6a9e431 100644 --- a/differential-dataflow/examples/columnar.rs +++ b/differential-dataflow/examples/columnar.rs @@ -392,7 +392,7 @@ pub mod batcher { ready: VecDeque, } - impl ContainerBuilder for Chunker { + impl ContainerBuilder for Chunker { type Container = C; fn extract(&mut self) -> Option<&mut Self::Container> { diff --git a/differential-dataflow/src/collection.rs b/differential-dataflow/src/collection.rs index 25ceb88b7..a35eca4fb 100644 --- a/differential-dataflow/src/collection.rs +++ b/differential-dataflow/src/collection.rs @@ -68,7 +68,7 @@ impl Collection { Collection { inner: stream, phantom: std::marker::PhantomData } } } -impl Collection { +impl Collection { /// Creates a new collection accumulating the contents of the two collections. /// /// Despite the name, differential dataflow collections are unordered. This method is so named because the @@ -686,7 +686,7 @@ where G: Scope, D: Data, R: Semigroup + 'static, - C: Container + Clone + 'static, + C: Container, I: IntoIterator>, { scope diff --git a/differential-dataflow/src/operators/arrange/arrangement.rs b/differential-dataflow/src/operators/arrange/arrangement.rs index 05cab5328..d2b043b88 100644 --- a/differential-dataflow/src/operators/arrange/arrangement.rs +++ b/differential-dataflow/src/operators/arrange/arrangement.rs @@ -31,6 +31,7 @@ use crate::difference::Semigroup; use crate::lattice::Lattice; use crate::trace::{self, Trace, TraceReader, BatchReader, Batcher, Builder, Cursor}; use crate::trace::implementations::{KeyBatcher, KeyBuilder, KeySpine, ValBatcher, ValBuilder, ValSpine}; +use crate::trace::implementations::merge_batcher::container::MergerChunk; use trace::wrappers::enter::{TraceEnter, BatchEnter,}; use trace::wrappers::enter_at::TraceEnter as TraceEnterAt; @@ -293,7 +294,7 @@ where Time=T1::Time, Diff: Abelian, >+'static, - Bu: Builder>, + Bu: Builder>, L: FnMut(T1::Key<'_>, &[(T1::Val<'_>, T1::Diff)], &mut Vec<(T2::ValOwn, T2::Diff)>)+'static, { self.reduce_core::<_,Bu,T2>(name, move |key, input, output, change| { @@ -315,7 +316,7 @@ where ValOwn: Data, Time=T1::Time, >+'static, - Bu: Builder>, + Bu: Builder>, L: FnMut(T1::Key<'_>, &[(T1::Val<'_>, T1::Diff)], &mut Vec<(T2::ValOwn, T2::Diff)>, &mut Vec<(T2::ValOwn, T2::Diff)>)+'static, { use crate::operators::reduce::reduce_trace; @@ -393,7 +394,7 @@ pub fn arrange_core(stream: &StreamCore, pact: P where G: Scope, P: ParallelizationContract, - Ba: Batcher + 'static, + Ba: Batcher + 'static, Bu: Builder, Tr: Trace+'static, { diff --git a/differential-dataflow/src/operators/iterate.rs b/differential-dataflow/src/operators/iterate.rs index 85bec781b..9bb4c55f6 100644 --- a/differential-dataflow/src/operators/iterate.rs +++ b/differential-dataflow/src/operators/iterate.rs @@ -156,7 +156,7 @@ where G: Scope, D: Data, R: Abelian + 'static, - C: Container + Clone + 'static, + C: Container, { collection: Collection, feedback: Handle, @@ -164,7 +164,7 @@ where step: ::Summary, } -impl Variable +impl Variable where G: Scope, StreamCore: crate::operators::Negate + ResultsIn, @@ -218,7 +218,7 @@ where } } -impl, D: Data, R: Abelian, C: Container + Clone + 'static> Deref for Variable { +impl, D: Data, R: Abelian, C: Container> Deref for Variable { type Target = Collection; fn deref(&self) -> &Self::Target { &self.collection @@ -236,14 +236,14 @@ where G: Scope, D: Data, R: Semigroup + 'static, - C: Container + Clone + 'static, + C: Container, { collection: Collection, feedback: Handle, step: ::Summary, } -impl SemigroupVariable +impl SemigroupVariable where G: Scope, StreamCore: ResultsIn, @@ -267,7 +267,7 @@ where } } -impl Deref for SemigroupVariable where G::Timestamp: Lattice { +impl Deref for SemigroupVariable where G::Timestamp: Lattice { type Target = Collection; fn deref(&self) -> &Self::Target { &self.collection diff --git a/differential-dataflow/src/operators/join.rs b/differential-dataflow/src/operators/join.rs index 17d590d9f..6392ea868 100644 --- a/differential-dataflow/src/operators/join.rs +++ b/differential-dataflow/src/operators/join.rs @@ -362,7 +362,7 @@ where T1: TraceReader+Clone+'static, T2: for<'a> TraceReader=T1::Key<'a>, Time=T1::Time>+Clone+'static, L: FnMut(T1::Key<'_>,T1::Val<'_>,T2::Val<'_>,&G::Timestamp,&T1::Diff,&T2::Diff,&mut JoinSession)+'static, - CB: ContainerBuilder + 'static, + CB: ContainerBuilder, { // Rename traces for symmetry from here on out. let mut trace1 = arranged1.trace.clone(); diff --git a/differential-dataflow/src/operators/reduce.rs b/differential-dataflow/src/operators/reduce.rs index 502b19690..b573ac8f6 100644 --- a/differential-dataflow/src/operators/reduce.rs +++ b/differential-dataflow/src/operators/reduce.rs @@ -5,7 +5,6 @@ //! to the key and the list of values. //! The function is expected to populate a list of output values. -use timely::Container; use timely::container::PushInto; use crate::hashable::Hashable; use crate::{Data, ExchangeData, Collection}; @@ -25,7 +24,7 @@ use crate::trace::{BatchReader, Cursor, Trace, Builder, ExertionLogic, Descripti use crate::trace::cursor::CursorList; use crate::trace::implementations::{KeySpine, KeyBuilder, ValSpine, ValBuilder}; use crate::trace::implementations::containers::BatchContainer; - +use crate::trace::implementations::merge_batcher::container::MergerChunk; use crate::trace::TraceReader; /// Extension trait for the `reduce` differential dataflow method. @@ -315,7 +314,7 @@ where G: Scope, T1: TraceReader + Clone + 'static, T2: for<'a> Trace=T1::Key<'a>, KeyOwn=T1::KeyOwn, ValOwn: Data, Time=T1::Time> + 'static, - Bu: Builder>, + Bu: Builder>, L: FnMut(T1::Key<'_>, &[(T1::Val<'_>, T1::Diff)], &mut Vec<(T2::ValOwn,T2::Diff)>, &mut Vec<(T2::ValOwn, T2::Diff)>)+'static, { let mut result_trace = None; @@ -533,8 +532,7 @@ where for (val, time, diff) in buffers[index].1.drain(..) { buffer.push_into(((T1::owned_key(key), val), time, diff)); builders[index].push(&mut buffer); - // TODO: Clear! - // buffer.clear(); + buffer.clear(); } } } diff --git a/differential-dataflow/src/trace/implementations/merge_batcher.rs b/differential-dataflow/src/trace/implementations/merge_batcher.rs index 37c247c86..ac3c05720 100644 --- a/differential-dataflow/src/trace/implementations/merge_batcher.rs +++ b/differential-dataflow/src/trace/implementations/merge_batcher.rs @@ -48,7 +48,7 @@ pub struct MergeBatcher { impl Batcher for MergeBatcher where - C: ContainerBuilder + Default + for<'a> PushInto<&'a mut Input>, + C: ContainerBuilder + for<'a> PushInto<&'a mut Input>, M: Merger, { type Input = Input; @@ -325,7 +325,7 @@ pub mod container { impl Merger for ContainerMerger where - for<'a> MC: MergerChunk + Clone + Default + PushInto<::Item<'a>> + 'static, + for<'a> MC: MergerChunk + Clone + PushInto<::Item<'a>> + 'static, CQ: ContainerQueue, { type Time = MC::TimeOwned; From d0c33a76ea38834cd32801fc59e537ce8100c116 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Mon, 15 Sep 2025 20:47:52 +0200 Subject: [PATCH 3/4] Address feedback Signed-off-by: Moritz Hoffmann --- differential-dataflow/src/collection.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/differential-dataflow/src/collection.rs b/differential-dataflow/src/collection.rs index a35eca4fb..69847a081 100644 --- a/differential-dataflow/src/collection.rs +++ b/differential-dataflow/src/collection.rs @@ -10,9 +10,7 @@ use std::hash::Hash; -use timely::Container; -use timely::container::IterContainer; -use timely::Data; +use timely::{Container, Data}; use timely::progress::Timestamp; use timely::order::Product; use timely::dataflow::scopes::{Child, child::Iterative}; @@ -156,7 +154,6 @@ impl Collection { pub fn inspect_container(&self, func: F) -> Self where F: FnMut(Result<(&G::Timestamp, &C), &[G::Timestamp]>)+'static, - C: IterContainer, { self.inner .inspect_container(func) From 0c56a5531820a2d1006daf69c1376524043f30ba Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Mon, 15 Sep 2025 21:18:34 +0200 Subject: [PATCH 4/4] Back to published Timely Signed-off-by: Moritz Hoffmann --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d184af962..1904c43b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,9 @@ resolver = "2" [workspace.dependencies] differential-dataflow = { path = "differential-dataflow", default-features = false, version = "0.16.2" } -#timely = { version = "0.23", default-features = false } +timely = { version = "0.24", default-features = false } columnar = { version = "0.10", default-features = false } -timely = { git = "https://github.com/TimelyDataflow/timely-dataflow", default-features = false } +#timely = { path = "../timely-dataflow/timely/", default-features = false } [profile.release] opt-level = 3