Type Alias VecCollection

Source
pub type VecCollection<G, D, R = isize> = Collection<G, Vec<(D, <G as ScopeParent>::Timestamp, R)>>;
Expand description

An evolving collection of values of type D, backed by Rust Vec types as containers.

The Collection type is the core abstraction in differential dataflow programs. As you write your differential dataflow computation, you write as if the collection is a static dataset to which you apply functional transformations, creating new collections. Once your computation is written, you are able to mutate the collection (by inserting and removing elements); differential dataflow will propagate changes through your functional computation and report the corresponding changes to the output collections.

Each vec collection has three generic parameters. The parameter G is for the scope in which the collection exists; as you write more complicated programs you may wish to introduce nested scopes (e.g. for iteration) and this parameter tracks the scope (for timely dataflow’s benefit). The D parameter is the type of data in your collection, for example String, or (u32, Vec<Option<()>>). The R parameter represents the types of changes that the data undergo, and is most commonly (and defaults to) isize, representing changes to the occurrence count of each record.

This type definition instantiates the Collection type with a Vec<(D, G::Timestamp, R)>.

Aliased Type§

pub struct VecCollection<G, D, R = isize> {
    pub inner: StreamCore<G, Vec<(D, <G as ScopeParent>::Timestamp, R)>>,
}

Fields§

§inner: StreamCore<G, Vec<(D, <G as ScopeParent>::Timestamp, R)>>

The underlying timely dataflow stream.

This field is exposed to support direct timely dataflow manipulation when required, but it is not intended to be the idiomatic way to work with the collection.

The timestamp in the data is required to always be at least the timestamp of the data, in the timely-dataflow sense. If this invariant is not upheld, differential operators may behave unexpectedly.

Implementations§

Source§

impl<G, D, R> VecCollection<G, D, R>
where G: Scope<Timestamp: Data + Lattice>, D: ExchangeData + Hashable, R: Semigroup + ExchangeData,

Methods which require data be arrangeable.

Source

pub fn consolidate(&self) -> Self

Aggregates the weights of equal records into at most one record.

This method uses the type D’s hashed() method to partition the data. The data are accumulated in place, each held back until their timestamp has completed.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {

    let x = scope.new_collection_from(1 .. 10u32).1;

    x.negate()
     .concat(&x)
     .consolidate() // <-- ensures cancellation occurs
     .assert_empty();
});
Source

pub fn consolidate_named<Ba, Bu, Tr, F>(&self, name: &str, reify: F) -> Self
where Ba: Batcher<Input = Vec<((D, ()), G::Timestamp, R)>, Time = G::Timestamp> + 'static, Tr: for<'a> Trace<Time = G::Timestamp, Diff = R> + 'static, Bu: Builder<Time = Tr::Time, Input = Ba::Output, Output = Tr::Batch>, F: Fn(Tr::Key<'_>, Tr::Val<'_>) -> D + 'static,

As consolidate but with the ability to name the operator, specify the trace type, and provide the function reify to produce owned keys and values..

Source

pub fn consolidate_stream(&self) -> Self

Aggregates the weights of equal records.

Unlike consolidate, this method does not exchange data and does not ensure that at most one copy of each (data, time) pair exists in the results. Instead, it acts on each batch of data and collapses equivalent (data, time) pairs found therein, suppressing any that accumulate to zero.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {

    let x = scope.new_collection_from(1 .. 10u32).1;

    // nothing to assert, as no particular guarantees.
    x.negate()
     .concat(&x)
     .consolidate_stream();
});
Source§

impl<G, D, R, T, TOuter> VecCollection<G, D, R>
where G: Scope<Timestamp = Product<TOuter, PointStamp<T>>>, D: Data, R: Semigroup + 'static, T: Timestamp + Default, TOuter: Timestamp,

Source

pub fn enter_dynamic(&self, _level: usize) -> Self

Enters a dynamically created scope which has level timestamp coordinates.

Source

pub fn leave_dynamic(&self, level: usize) -> Self

Leaves a dynamically created scope which has level timestamp coordinates.

Source§

impl<G: Scope, D: Clone + 'static, R: Clone + 'static> VecCollection<G, D, R>

Source

pub fn map<D2, L>(&self, logic: L) -> VecCollection<G, D2, R>
where D2: Data, L: FnMut(D) -> D2 + 'static,

Creates a new collection by applying the supplied function to each input element.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .map(|x| x * 2)
         .filter(|x| x % 2 == 1)
         .assert_empty();
});
Source

pub fn map_in_place<L>(&self, logic: L) -> VecCollection<G, D, R>
where L: FnMut(&mut D) + 'static,

Creates a new collection by applying the supplied function to each input element.

Although the name suggests in-place mutation, this function does not change the source collection, but rather re-uses the underlying allocations in its implementation. The method is semantically equivalent to map, but can be more efficient.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .map_in_place(|x| *x *= 2)
         .filter(|x| x % 2 == 1)
         .assert_empty();
});
Source

pub fn flat_map<I, L>(&self, logic: L) -> VecCollection<G, I::Item, R>
where G::Timestamp: Clone, I: IntoIterator<Item: Data>, L: FnMut(D) -> I + 'static,

Creates a new collection by applying the supplied function to each input element and accumulating the results.

This method extracts an iterator from each input element, and extracts the full contents of the iterator. Be warned that if the iterators produce substantial amounts of data, they are currently fully drained before attempting to consolidate the results.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .flat_map(|x| 0 .. x);
});
Source

pub fn filter<L>(&self, logic: L) -> VecCollection<G, D, R>
where L: FnMut(&D) -> bool + 'static,

Creates a new collection containing those input records satisfying the supplied predicate.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .map(|x| x * 2)
         .filter(|x| x % 2 == 1)
         .assert_empty();
});
Source

pub fn explode<D2, R2, I, L>( &self, logic: L, ) -> VecCollection<G, D2, <R2 as Multiply<R>>::Output>
where D2: Data, R2: Semigroup + Multiply<R, Output: Semigroup + 'static>, I: IntoIterator<Item = (D2, R2)>, L: FnMut(D) -> I + 'static,

Replaces each record with another, with a new difference type.

This method is most commonly used to take records containing aggregatable data (e.g. numbers to be summed) and move the data into the difference component. This will allow differential dataflow to update in-place.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {

    let nums = scope.new_collection_from(0 .. 10).1;
    let x1 = nums.flat_map(|x| 0 .. x);
    let x2 = nums.map(|x| (x, 9 - x))
                 .explode(|(x,y)| Some((x,y)));

    x1.assert_eq(&x2);
});
Source

pub fn join_function<D2, R2, I, L>( &self, logic: L, ) -> VecCollection<G, D2, <R2 as Multiply<R>>::Output>
where G::Timestamp: Lattice, D2: Data, R2: Semigroup + Multiply<R, Output: Semigroup + 'static>, I: IntoIterator<Item = (D2, G::Timestamp, R2)>, L: FnMut(D) -> I + 'static,

Joins each record against a collection defined by the function logic.

This method performs what is essentially a join with the collection of records (x, logic(x)). Rather than materialize this second relation, logic is applied to each record and the appropriate modifications made to the results, namely joining timestamps and multiplying differences.

#Examples

use differential_dataflow::input::Input;

::timely::example(|scope| {
    // creates `x` copies of `2*x` from time `3*x` until `4*x`,
    // for x from 0 through 9.
    scope.new_collection_from(0 .. 10isize).1
         .join_function(|x|
             //   data      time      diff
             vec![(2*x, (3*x) as u64,  x),
                  (2*x, (4*x) as u64, -x)]
          );
});
Source

pub fn enter_at<'a, T, F>( &self, child: &Iterative<'a, G, T>, initial: F, ) -> VecCollection<Iterative<'a, G, T>, D, R>
where T: Timestamp + Hash, F: FnMut(&D) -> T + Clone + 'static, G::Timestamp: Hash,

Brings a Collection into a nested scope, at varying times.

The initial function indicates the time at which each element of the Collection should appear.

§Examples
use timely::dataflow::Scope;
use differential_dataflow::input::Input;

::timely::example(|scope| {

    let data = scope.new_collection_from(1 .. 10).1;

    let result = scope.iterative::<u64,_,_>(|child| {
        data.enter_at(child, |x| *x)
            .leave()
    });

    data.assert_eq(&result);
});
Source

pub fn delay<F>(&self, func: F) -> VecCollection<G, D, R>
where G::Timestamp: Hash, F: FnMut(&G::Timestamp) -> G::Timestamp + Clone + 'static,

Delays each difference by a supplied function.

It is assumed that func only advances timestamps; this is not verified, and things may go horribly wrong if that assumption is incorrect. It is also critical that func be monotonic: if two times are ordered, they should have the same order or compare equal once func is applied to them (this is because we advance the timely capability with the same logic, and it must remain less_equal to all of the data timestamps).

Source

pub fn inspect<F>(&self, func: F) -> VecCollection<G, D, R>
where F: FnMut(&(D, G::Timestamp, R)) + 'static,

Applies a supplied function to each update.

This method is most commonly used to report information back to the user, often for debugging purposes. Any function can be used here, but be warned that the incremental nature of differential dataflow does not guarantee that it will be called as many times as you might expect.

The (data, time, diff) triples indicate a change diff to the frequency of data which takes effect at the logical time time. When times are totally ordered (for example, usize), these updates reflect the changes along the sequence of collections. For partially ordered times, the mathematics are more interesting and less intuitive, unfortunately.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .map_in_place(|x| *x *= 2)
         .filter(|x| x % 2 == 1)
         .inspect(|x| println!("error: {:?}", x));
});
Source

pub fn inspect_batch<F>(&self, func: F) -> VecCollection<G, D, R>
where F: FnMut(&G::Timestamp, &[(D, G::Timestamp, R)]) + 'static,

Applies a supplied function to each batch of updates.

This method is analogous to inspect, but operates on batches and reveals the timestamp of the timely dataflow capability associated with the batch of updates. The observed batching depends on how the system executes, and may vary run to run.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .map_in_place(|x| *x *= 2)
         .filter(|x| x % 2 == 1)
         .inspect_batch(|t,xs| println!("errors @ {:?}: {:?}", t, xs));
});
Source

pub fn assert_empty(&self)

Assert if the collection is ever non-empty.

Because this is a dataflow fragment, the test is only applied as the computation is run. If the computation is not run, or not run to completion, there may be un-exercised times at which the collection could be non-empty. Typically, a timely dataflow computation runs to completion on drop, and so clean exit from a program should indicate that this assertion never found cause to complain.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {
    scope.new_collection_from(1 .. 10).1
         .map(|x| x * 2)
         .filter(|x| x % 2 == 1)
         .assert_empty();
});
Source§

impl<G: Scope<Timestamp: Data>, D: Clone + 'static, R: Abelian + 'static> VecCollection<G, D, R>

Methods requiring an Abelian difference, to support negation.

Source

pub fn assert_eq(&self, other: &Self)

Assert if the collections are ever different.

Because this is a dataflow fragment, the test is only applied as the computation is run. If the computation is not run, or not run to completion, there may be un-exercised times at which the collections could vary. Typically, a timely dataflow computation runs to completion on drop, and so clean exit from a program should indicate that this assertion never found cause to complain.

§Examples
use differential_dataflow::input::Input;

::timely::example(|scope| {

    let data = scope.new_collection_from(1 .. 10).1;

    let odds = data.filter(|x| x % 2 == 1);
    let evens = data.filter(|x| x % 2 == 0);

    odds.concat(&evens)
        .assert_eq(&data);
});

Trait Implementations§

Source§

impl<G, K: ExchangeData + Hashable, R: ExchangeData + Semigroup> Arrange<G, Vec<((K, ()), <G as ScopeParent>::Timestamp, R)>> for VecCollection<G, K, R>
where G: Scope<Timestamp: Lattice + Ord>,

Source§

fn arrange_named<Ba, Bu, Tr>(&self, name: &str) -> Arranged<G, TraceAgent<Tr>>
where Ba: Batcher<Input = Vec<((K, ()), G::Timestamp, R)>, Time = G::Timestamp> + 'static, Bu: Builder<Time = G::Timestamp, Input = Ba::Output, Output = Tr::Batch>, Tr: Trace<Time = G::Timestamp> + 'static,

Arranges updates into a shared trace, with a supplied name.
Source§

fn arrange<Ba, Bu, Tr>(&self) -> Arranged<G, TraceAgent<Tr>>
where Ba: Batcher<Input = C, Time = G::Timestamp> + 'static, Bu: Builder<Time = G::Timestamp, Input = Ba::Output, Output = Tr::Batch>, Tr: Trace<Time = G::Timestamp> + 'static,

Arranges updates into a shared trace.
Source§

impl<G, K, V, R> Arrange<G, Vec<((K, V), <G as ScopeParent>::Timestamp, R)>> for VecCollection<G, (K, V), R>
where G: Scope<Timestamp: Lattice>, K: ExchangeData + Hashable, V: ExchangeData, R: ExchangeData + Semigroup,

Source§

fn arrange_named<Ba, Bu, Tr>(&self, name: &str) -> Arranged<G, TraceAgent<Tr>>
where Ba: Batcher<Input = Vec<((K, V), G::Timestamp, R)>, Time = G::Timestamp> + 'static, Bu: Builder<Time = G::Timestamp, Input = Ba::Output, Output = Tr::Batch>, Tr: Trace<Time = G::Timestamp> + 'static,

Arranges updates into a shared trace, with a supplied name.
Source§

fn arrange<Ba, Bu, Tr>(&self) -> Arranged<G, TraceAgent<Tr>>
where Ba: Batcher<Input = C, Time = G::Timestamp> + 'static, Bu: Builder<Time = G::Timestamp, Input = Ba::Output, Output = Tr::Batch>, Tr: Trace<Time = G::Timestamp> + 'static,

Arranges updates into a shared trace.
Source§

impl<G, K: ExchangeData + Hashable, V: ExchangeData, R: ExchangeData + Semigroup> ArrangeByKey<G, K, V, R> for VecCollection<G, (K, V), R>
where G: Scope<Timestamp: Lattice + Ord>,

Source§

fn arrange_by_key( &self, ) -> Arranged<G, TraceAgent<ValSpine<K, V, G::Timestamp, R>>>

Arranges a collection of (Key, Val) records by Key. Read more
Source§

fn arrange_by_key_named( &self, name: &str, ) -> Arranged<G, TraceAgent<ValSpine<K, V, G::Timestamp, R>>>

As arrange_by_key but with the ability to name the arrangement.
Source§

impl<G, K: ExchangeData + Hashable, R: ExchangeData + Semigroup> ArrangeBySelf<G, K, R> for VecCollection<G, K, R>
where G: Scope<Timestamp: Lattice + Ord>,

Source§

fn arrange_by_self( &self, ) -> Arranged<G, TraceAgent<KeySpine<K, G::Timestamp, R>>>

Arranges a collection of Key records by Key. Read more
Source§

fn arrange_by_self_named( &self, name: &str, ) -> Arranged<G, TraceAgent<KeySpine<K, G::Timestamp, R>>>

As arrange_by_self but with the ability to name the arrangement.
Source§

impl<G: Scope<Timestamp: Lattice + Ord>, K: ExchangeData + Hashable, R: ExchangeData + Semigroup> Count<G, K, R> for VecCollection<G, K, R>

Source§

fn count_core<R2: Ord + Abelian + From<i8> + 'static>( &self, ) -> VecCollection<G, (K, R), R2>

Count for general integer differences. Read more
Source§

fn count(&self) -> VecCollection<G, (K, R), isize>

Counts the number of occurrences of each element. Read more
Source§

impl<G, K: ExchangeData + Hashable, R: ExchangeData + Semigroup> CountTotal<G, K, R> for VecCollection<G, K, R>
where G: Scope<Timestamp: TotalOrder + Lattice + Ord>,

Source§

fn count_total_core<R2: Semigroup + From<i8> + 'static>( &self, ) -> VecCollection<G, (K, R), R2>

Count for general integer differences. Read more
Source§

fn count_total(&self) -> VecCollection<G, (K, R), isize>

Counts the number of occurrences of each element. Read more
Source§

impl<G, D, R> Identifiers<G, D, R> for VecCollection<G, D, R>
where G: Scope<Timestamp: Lattice>, D: ExchangeData + Hash, R: ExchangeData + Abelian,

Source§

fn identifiers(&self) -> VecCollection<G, (D, u64), R>

Assign unique identifiers to elements of a collection. Read more
Source§

impl<G: Scope<Timestamp: Lattice>, D: Ord + Data + Debug, R: Abelian + 'static> Iterate<G, D, R> for VecCollection<G, D, R>

Source§

fn iterate<F>(&self, logic: F) -> VecCollection<G, D, R>
where for<'a> F: FnOnce(&VecCollection<Iterative<'a, G, u64>, D, R>) -> VecCollection<Iterative<'a, G, u64>, D, R>,

Iteratively apply logic to the source collection until convergence. Read more
Source§

impl<G, K, V, R> Join<G, K, V, R> for VecCollection<G, (K, V), R>
where G: Scope<Timestamp: Lattice + Ord>, K: ExchangeData + Hashable, V: ExchangeData, R: ExchangeData + Semigroup,

Source§

fn join_map<V2: ExchangeData, R2: ExchangeData + Semigroup, D: Data, L>( &self, other: &VecCollection<G, (K, V2), R2>, logic: L, ) -> VecCollection<G, D, <R as Multiply<R2>>::Output>
where R: Multiply<R2, Output: Semigroup + 'static>, L: FnMut(&K, &V, &V2) -> D + 'static,

Matches pairs (key,val1) and (key,val2) based on key and then applies a function. Read more
Source§

fn semijoin<R2: ExchangeData + Semigroup>( &self, other: &VecCollection<G, K, R2>, ) -> VecCollection<G, (K, V), <R as Multiply<R2>>::Output>
where R: Multiply<R2, Output: Semigroup + 'static>,

Matches pairs (key, val) and key based on key, producing the former with frequencies multiplied. Read more
Source§

fn antijoin<R2: ExchangeData + Semigroup>( &self, other: &VecCollection<G, K, R2>, ) -> VecCollection<G, (K, V), R>
where R: Multiply<R2, Output = R> + Abelian + 'static,

Subtracts the semijoin with other from self. Read more
Source§

fn join<V2, R2>( &self, other: &VecCollection<G, (K, V2), R2>, ) -> VecCollection<G, (K, (V, V2)), <R as Multiply<R2>>::Output>
where K: ExchangeData, V2: ExchangeData, R2: ExchangeData + Semigroup, R: Multiply<R2, Output: Semigroup + 'static>,

Matches pairs (key,val1) and (key,val2) based on key and yields pairs (key, (val1, val2)). Read more
Source§

impl<G, K, V, R> JoinCore<G, K, V, R> for VecCollection<G, (K, V), R>
where G: Scope<Timestamp: Lattice + Ord>, K: ExchangeData + Hashable, V: ExchangeData, R: ExchangeData + Semigroup,

Source§

fn join_core<Tr2, I, L>( &self, stream2: &Arranged<G, Tr2>, result: L, ) -> VecCollection<G, I::Item, <R as Multiply<Tr2::Diff>>::Output>
where Tr2: for<'a> TraceReader<Key<'a> = &'a K, Time = G::Timestamp> + Clone + 'static, R: Multiply<Tr2::Diff, Output: Semigroup + 'static>, I: IntoIterator<Item: Data>, L: FnMut(&K, &V, Tr2::Val<'_>) -> I + 'static,

Joins two arranged collections with the same key type. Read more
Source§

fn join_core_internal_unsafe<Tr2, I, L, D, ROut>( &self, stream2: &Arranged<G, Tr2>, result: L, ) -> VecCollection<G, D, ROut>
where Tr2: for<'a> TraceReader<Key<'a> = &'a K, Time = G::Timestamp> + Clone + 'static, I: IntoIterator<Item = (D, G::Timestamp, ROut)>, L: FnMut(&K, &V, Tr2::Val<'_>, &G::Timestamp, &R, &Tr2::Diff) -> I + 'static, D: Data, ROut: Semigroup + 'static,

An unsafe variant of join_core where the result closure takes additional arguments for time and diff as input and returns an iterator over (data, time, diff) triplets. This allows for more flexibility, but is more error-prone. Read more
Source§

impl<G, K, D> PrefixSum<G, K, D> for VecCollection<G, ((usize, K), D)>
where G: Scope<Timestamp: Lattice>, K: ExchangeData + Hash, D: ExchangeData + Hash,

Source§

fn prefix_sum<F>(&self, zero: D, combine: F) -> Self
where F: Fn(&K, &D, &D) -> D + 'static,

Computes the prefix sum for each element in the collection. Read more
Source§

fn prefix_sum_at<F>( &self, locations: VecCollection<G, (usize, K)>, zero: D, combine: F, ) -> Self
where F: Fn(&K, &D, &D) -> D + 'static,

Determine the prefix sum at each element of location.
Source§

impl<G, K, V, R> Reduce<G, K, V, R> for VecCollection<G, (K, V), R>
where G: Scope<Timestamp: Lattice + Ord>, K: ExchangeData + Hashable, V: ExchangeData, R: ExchangeData + Semigroup,

Source§

fn reduce_named<L, V2: Data, R2: Ord + Abelian + 'static>( &self, name: &str, logic: L, ) -> VecCollection<G, (K, V2), R2>
where L: FnMut(&K, &[(&V, R)], &mut Vec<(V2, R2)>) + 'static,

As reduce with the ability to name the operator.
Source§

fn reduce<L, V2: Data, R2: Ord + Abelian + 'static>( &self, logic: L, ) -> VecCollection<G, (K, V2), R2>
where L: FnMut(&K, &[(&V, R)], &mut Vec<(V2, R2)>) + 'static,

Applies a reduction function on records grouped by key. Read more
Source§

impl<G, K, V, R> ReduceCore<G, K, V, R> for VecCollection<G, (K, V), R>

Source§

fn reduce_core<L, Bu, T2>( &self, name: &str, logic: L, ) -> Arranged<G, TraceAgent<T2>>
where V: Data, T2: for<'a> Trace<Key<'a> = &'a K, KeyOwn = K, ValOwn = V, Time = G::Timestamp> + 'static, Bu: Builder<Time = T2::Time, Input = Vec<((K, V), T2::Time, T2::Diff)>, Output = T2::Batch>, L: FnMut(&K, &[(&V, R)], &mut Vec<(V, T2::Diff)>, &mut Vec<(V, T2::Diff)>) + 'static,

Solves for output updates when presented with inputs and would-be outputs. Read more
Source§

fn reduce_abelian<L, Bu, T2>( &self, name: &str, logic: L, ) -> Arranged<G, TraceAgent<T2>>
where T2: for<'a> Trace<Key<'a> = &'a K, KeyOwn = K, ValOwn = V, Time = G::Timestamp, Diff: Abelian> + 'static, Bu: Builder<Time = T2::Time, Input = Vec<((K::Owned, V), T2::Time, T2::Diff)>, Output = T2::Batch>, L: FnMut(&K, &[(&V, R)], &mut Vec<(V, T2::Diff)>) + 'static,

Applies reduce to arranged data, and returns an arrangement of output data. Read more
Source§

impl<G: Scope<Timestamp: Lattice + Ord>, K: ExchangeData + Hashable, R1: ExchangeData + Semigroup> Threshold<G, K, R1> for VecCollection<G, K, R1>

Source§

fn threshold_named<R2: Ord + Abelian + 'static, F: FnMut(&K, &R1) -> R2 + 'static>( &self, name: &str, thresh: F, ) -> VecCollection<G, K, R2>

A threshold with the ability to name the operator.
Source§

fn threshold<R2: Ord + Abelian + 'static, F: FnMut(&K, &R1) -> R2 + 'static>( &self, thresh: F, ) -> VecCollection<G, K, R2>

Transforms the multiplicity of records. Read more
Source§

fn distinct(&self) -> VecCollection<G, K, isize>

Reduces the collection to one occurrence of each distinct element. Read more
Source§

fn distinct_core<R2: Ord + Abelian + 'static + From<i8>>( &self, ) -> VecCollection<G, K, R2>

Distinct for general integer differences. Read more
Source§

impl<G, K: ExchangeData + Hashable, R: ExchangeData + Semigroup> ThresholdTotal<G, K, R> for VecCollection<G, K, R>
where G: Scope<Timestamp: TotalOrder + Lattice + Ord> + Scope,

Source§

fn threshold_semigroup<R2, F>(&self, thresh: F) -> VecCollection<G, K, R2>
where R2: Semigroup + 'static, F: FnMut(&K, &R, Option<&R>) -> Option<R2> + 'static,

Reduces the collection to one occurrence of each distinct element.
Source§

fn threshold_total<R2: Abelian + 'static, F: FnMut(&K, &R) -> R2 + 'static>( &self, thresh: F, ) -> VecCollection<G, K, R2>

Reduces the collection to one occurrence of each distinct element. Read more
Source§

fn distinct_total(&self) -> VecCollection<G, K, isize>

Reduces the collection to one occurrence of each distinct element. Read more
Source§

fn distinct_total_core<R2: Abelian + From<i8> + 'static>( &self, ) -> VecCollection<G, K, R2>

Distinct for general integer differences. Read more