timely/dataflow/operators/generic/
builder_raw.rs1use std::default::Default;
8use std::rc::Rc;
9use std::cell::RefCell;
10
11use crate::scheduling::{Schedule, Activations};
12
13use crate::progress::{Source, Target};
14use crate::progress::{Timestamp, Operate, operate::SharedProgress, Antichain};
15use crate::progress::operate::{FrontierInterest, Connectivity, PortConnectivityBuilder};
16use crate::Container;
17use crate::dataflow::{Stream, Scope, OperatorSlot};
18use crate::dataflow::channels::pushers::Tee;
19use crate::dataflow::channels::pact::ParallelizationContract;
20use crate::dataflow::operators::generic::operator_info::OperatorInfo;
21
22#[derive(Debug)]
24pub struct OperatorShape {
25 name: String, notify: Vec<FrontierInterest>, peers: usize, inputs: usize, outputs: usize, }
31
32impl OperatorShape {
34 fn new(name: String, peers: usize) -> Self {
35 OperatorShape {
36 name,
37 notify: Vec::new(),
38 peers,
39 inputs: 0,
40 outputs: 0,
41 }
42 }
43
44 pub fn inputs(&self) -> usize { self.inputs }
46
47 pub fn outputs(&self) -> usize { self.outputs }
49}
50
51#[derive(Debug)]
53pub struct OperatorBuilder<'scope, T: Timestamp> {
54 scope: Scope<'scope, T>,
55 slot: OperatorSlot<'scope, T>,
56 address: Rc<[usize]>, shape: OperatorShape,
58 summary: Vec<PortConnectivityBuilder<<T as Timestamp>::Summary>>,
59}
60
61impl<'scope, T: Timestamp> OperatorBuilder<'scope, T> {
62
63 pub fn new(name: String, scope: Scope<'scope, T>) -> Self {
65
66 let slot = scope.reserve_operator();
67 let address = slot.addr();
68 let peers = scope.peers();
69
70 OperatorBuilder {
71 scope,
72 slot,
73 address,
74 shape: OperatorShape::new(name, peers),
75 summary: vec![],
76 }
77 }
78
79 pub fn index(&self) -> usize { self.slot.index() }
81
82 pub fn global(&self) -> usize { self.slot.identifier() }
84
85 pub fn shape(&self) -> &OperatorShape { &self.shape }
87
88 pub fn set_notify_for(&mut self, input: usize, notify: FrontierInterest) {
90 self.shape.notify[input] = notify;
91 }
92
93 pub fn new_input<C: Container, P>(&mut self, stream: Stream<'scope, T, C>, pact: P) -> P::Puller
95 where
96 P: ParallelizationContract<T, C>
97 {
98 let connection = (0 .. self.shape.outputs).map(|o| (o, Antichain::from_elem(Default::default())));
99 self.new_input_connection(stream, pact, connection)
100 }
101
102 pub fn new_input_connection<C: Container, P, I>(&mut self, stream: Stream<'scope, T, C>, pact: P, connection: I) -> P::Puller
104 where
105 P: ParallelizationContract<T, C>,
106 I: IntoIterator<Item = (usize, Antichain<<T as Timestamp>::Summary>)>,
107 {
108 let channel_id = self.scope.worker().new_identifier();
109 let logging = self.scope.worker().logging();
110 let (sender, receiver) = pact.connect(self.scope.worker(), channel_id, Rc::clone(&self.address), logging);
111 let target = Target::new(self.slot.index(), self.shape.inputs);
112 stream.connect_to(target, sender, channel_id);
113
114 self.shape.inputs += 1;
115 self.shape.notify.push(FrontierInterest::Always);
116 let connectivity: PortConnectivityBuilder<_> = connection.into_iter()
117 .inspect(|(o,_)| assert!(*o < self.shape.outputs))
118 .collect();
119 self.summary.push(connectivity);
120
121 receiver
122 }
123
124 pub fn new_output<C: Container>(&mut self) -> (Tee<T, C>, Stream<'scope, T, C>) {
126 let connection = (0 .. self.shape.inputs).map(|i| (i, Antichain::from_elem(Default::default())));
127 self.new_output_connection(connection)
128 }
129
130 pub fn new_output_connection<C: Container, I>(&mut self, connection: I) -> (Tee<T, C>, Stream<'scope, T, C>)
132 where
133 I: IntoIterator<Item = (usize, Antichain<<T as Timestamp>::Summary>)>,
134 {
135 let new_output = self.shape.outputs;
136 self.shape.outputs += 1;
137 let (target, registrar) = Tee::new();
138 let source = Source::new(self.slot.index(), new_output);
139 let stream = Stream::new(source, registrar, self.scope);
140
141 for (input, entry) in connection {
142 self.summary[input].add_port(new_output, entry);
143 }
144
145 (target, stream)
146 }
147
148 pub fn build<L>(self, logic: L)
153 where
154 L: FnMut(&mut SharedProgress<T>)->bool+'static
155 {
156 self.build_boxed(Box::new(logic));
157 }
158
159 pub fn build_boxed(self, logic: Box<dyn FnMut(&mut SharedProgress<T>)->bool>) {
164 self.build_typed(logic);
165 }
166
167 pub fn build_typed<L>(self, logic: L)
174 where
175 L: FnMut(&mut SharedProgress<T>)->bool+'static
176 {
177 let inputs = self.shape.inputs;
178 let outputs = self.shape.outputs;
179
180 let operator = OperatorCore {
181 shape: self.shape,
182 address: self.address,
183 activations: self.scope.activations(),
184 logic,
185 shared_progress: Rc::new(RefCell::new(SharedProgress::new(inputs, outputs))),
186 summary: self.summary.into_iter().map(|b| b.freeze()).collect(),
187 };
188
189 self.slot.install(Box::new(operator));
190 }
191
192 pub fn operator_info(&self) -> OperatorInfo {
194 OperatorInfo::new(self.index(), self.global(), Rc::clone(&self.address))
195 }
196}
197
198struct OperatorCore<T, L>
199where
200 T: Timestamp,
201 L: FnMut(&mut SharedProgress<T>)->bool+'static,
202{
203 shape: OperatorShape,
204 address: Rc<[usize]>,
205 logic: L,
206 shared_progress: Rc<RefCell<SharedProgress<T>>>,
207 activations: Rc<RefCell<Activations>>,
208 summary: Connectivity<T::Summary>,
209}
210
211impl<T, L> Schedule for OperatorCore<T, L>
212where
213 T: Timestamp,
214 L: FnMut(&mut SharedProgress<T>)->bool+'static,
215{
216 fn name(&self) -> &str { &self.shape.name }
217 fn path(&self) -> &[usize] { &self.address[..] }
218 fn schedule(&mut self) -> bool {
219 let shared_progress = &mut *self.shared_progress.borrow_mut();
220 (self.logic)(shared_progress)
221 }
222}
223
224impl<T, L> Operate<T> for OperatorCore<T, L>
225where
226 T: Timestamp,
227 L: FnMut(&mut SharedProgress<T>)->bool+'static,
228{
229 fn inputs(&self) -> usize { self.shape.inputs }
230 fn outputs(&self) -> usize { self.shape.outputs }
231
232 fn initialize(mut self: Box<Self>) -> (Connectivity<T::Summary>, Rc<RefCell<SharedProgress<T>>>, Box<dyn Schedule>) {
234
235 self.activations.borrow_mut().activate(&self.address[..]);
237
238 self.shared_progress
240 .borrow_mut()
241 .internals
242 .iter_mut()
243 .for_each(|output| output.update(T::minimum(), self.shape.peers as i64));
244
245 (::std::mem::take(&mut self.summary), Rc::clone(&self.shared_progress), self)
247 }
248
249 fn notify_me(&self) -> &[FrontierInterest] { &self.shape.notify }
250}