differential_dogs3/operators/
propose.rs

1use timely::dataflow::Scope;
2
3use differential_dataflow::{ExchangeData, Collection, Hashable};
4use differential_dataflow::difference::{Semigroup, Monoid, Multiply};
5use differential_dataflow::operators::arrange::Arranged;
6use differential_dataflow::trace::TraceReader;
7use differential_dataflow::trace::cursor::IntoOwned;
8
9/// Proposes extensions to a prefix stream.
10///
11/// This method takes a collection `prefixes` and an arrangement `arrangement` and for each
12/// update in the collection joins with the accumulated arranged records at a time less or
13/// equal to that of the update. Note that this is not a join by itself, but can be used to
14/// create a join if the `prefixes` collection is also arranged and responds to changes that
15/// `arrangement` undergoes. More complicated patterns are also appropriate, as in the case
16/// of delta queries.
17pub fn propose<G, Tr, K, F, P, V>(
18    prefixes: &Collection<G, P, Tr::Diff>,
19    arrangement: Arranged<G, Tr>,
20    key_selector: F,
21) -> Collection<G, (P, V), Tr::Diff>
22where
23    G: Scope<Timestamp=Tr::Time>,
24    Tr: TraceReader+Clone+'static,
25    for<'a> Tr::Key<'a> : IntoOwned<'a, Owned = K>,
26    K: Hashable + Default + Ord + 'static,
27    Tr::Diff: Monoid+Multiply<Output = Tr::Diff>+ExchangeData,
28    for<'a> Tr::Diff : Semigroup<Tr::DiffGat<'a>>,
29    F: Fn(&P)->K+Clone+'static,
30    P: ExchangeData,
31    V: Clone + 'static,
32    for<'a> Tr::Val<'a> : IntoOwned<'a, Owned = V>,
33{
34    crate::operators::lookup_map(
35        prefixes,
36        arrangement,
37        move |p: &P, k: &mut K | { *k = key_selector(p); },
38        move |prefix, diff, value, sum| ((prefix.clone(), value.into_owned()), diff.clone().multiply(sum)),
39        Default::default(),
40        Default::default(),
41        Default::default(),
42    )
43}
44
45/// Proposes distinct extensions to a prefix stream.
46///
47/// Unlike `propose`, this method does not scale the multiplicity of matched
48/// prefixes by the number of matches in `arrangement`. This can be useful to
49/// avoid the need to prepare an arrangement of distinct extensions.
50pub fn propose_distinct<G, Tr, K, F, P, V>(
51    prefixes: &Collection<G, P, Tr::Diff>,
52    arrangement: Arranged<G, Tr>,
53    key_selector: F,
54) -> Collection<G, (P, V), Tr::Diff>
55where
56    G: Scope<Timestamp=Tr::Time>,
57    Tr: TraceReader+Clone+'static,
58    for<'a> Tr::Key<'a> : IntoOwned<'a, Owned = K>,
59    for<'a> Tr::Diff : Semigroup<Tr::DiffGat<'a>>,
60    K: Hashable + Default + Ord + 'static,
61    Tr::Diff: Monoid+Multiply<Output = Tr::Diff>+ExchangeData,
62    F: Fn(&P)->K+Clone+'static,
63    P: ExchangeData,
64    V: Clone + 'static,
65    for<'a> Tr::Val<'a> : IntoOwned<'a, Owned = V>,
66{
67    crate::operators::lookup_map(
68        prefixes,
69        arrangement,
70        move |p: &P, k: &mut K| { *k = key_selector(p); },
71        move |prefix, diff, value, _sum| ((prefix.clone(), value.into_owned()), diff.clone()),
72        Default::default(),
73        Default::default(),
74        Default::default(),
75    )
76}