timely/dataflow/operators/generic/
handles.rs1use std::rc::Rc;
7use std::cell::{OnceCell, RefCell};
8use std::collections::VecDeque;
9
10use crate::progress::Timestamp;
11use crate::progress::ChangeBatch;
12use crate::progress::operate::PortConnectivity;
13use crate::dataflow::channels::pullers::Counter as PullCounter;
14use crate::dataflow::channels::Message;
15use crate::communication::Pull;
16use crate::{Container, ContainerBuilder, Accountable};
17use crate::container::{CapacityContainerBuilder, PushInto};
18
19use crate::dataflow::operators::InputCapability;
20use crate::dataflow::operators::capability::CapabilityTrait;
21
22pub struct InputHandleCore<T: Timestamp, C, P: Pull<Message<T, C>>> {
24 pull_counter: PullCounter<T, C, P>,
25 internal: Rc<RefCell<Vec<Rc<RefCell<ChangeBatch<T>>>>>>,
26 summaries: Rc<OnceCell<PortConnectivity<T::Summary>>>,
31 staging: VecDeque<(InputCapability<T>, C)>,
33 staged: Vec<C>,
34}
35
36impl<T: Timestamp, C: Accountable, P: Pull<Message<T, C>>> InputHandleCore<T, C, P> {
37 #[inline]
42 fn next(&mut self) -> Option<(InputCapability<T>, &mut C)> {
43 let internal = &self.internal;
44 let summaries = &self.summaries;
45 self.pull_counter.next_guarded().map(|(guard, bundle)| {
46 (InputCapability::new(Rc::clone(internal), Rc::clone(summaries), guard), &mut bundle.data)
47 })
48 }
49 pub fn for_each<F>(&mut self, mut logic: F) where F: FnMut(InputCapability<T>, &mut C) {
54 while let Some((cap, data)) = self.next() { logic(cap, data); }
55 }
56 pub fn for_each_stamp<F>(&mut self, mut logic: F) where F: FnMut(InputCapability<T>, std::slice::IterMut::<C>), C: Default {
61 while let Some((cap, data)) = self.next() {
62 let data = std::mem::take(data);
63 self.staging.push_back((cap, data));
64 }
65 self.staging.make_contiguous().sort_unstable_by(|x,y| x.0.stamp().cmp(y.0.stamp()));
66
67 while let Some((cap, data)) = self.staging.pop_front() {
68 self.staged.push(data);
69 let more = self.staging.iter().take_while(|(c,_)| c.stamp() == cap.stamp()).count();
70 self.staged.extend(self.staging.drain(..more).map(|(_,d)| d));
71 logic(cap, self.staged.iter_mut());
72 self.staged.clear();
74 }
75 }
76 #[deprecated(note = "renamed to `for_each_stamp`: containers are grouped by stamp, not by a time")]
78 pub fn for_each_time<F>(&mut self, logic: F) where F: FnMut(InputCapability<T>, std::slice::IterMut::<C>), C: Default {
79 self.for_each_stamp(logic)
80 }
81}
82
83pub fn new_input_handle<T: Timestamp, C: Accountable, P: Pull<Message<T, C>>>(
86 pull_counter: PullCounter<T, C, P>,
87 internal: Rc<RefCell<Vec<Rc<RefCell<ChangeBatch<T>>>>>>,
88 summaries: Rc<OnceCell<PortConnectivity<T::Summary>>>,
89) -> InputHandleCore<T, C, P> {
90 InputHandleCore {
91 pull_counter,
92 internal,
93 summaries,
94 staging: Default::default(),
95 staged: Default::default(),
96 }
97}
98
99pub struct OutputBuilder<T: Timestamp, CB: ContainerBuilder> {
101 output: crate::dataflow::channels::pushers::Output<T, CB::Container>,
102 builder: CB,
103}
104
105impl<T: Timestamp, CB: ContainerBuilder> OutputBuilder<T, CB> {
106 pub fn from(output: crate::dataflow::channels::pushers::Output<T, CB::Container>) -> Self {
108 Self { output, builder: CB::default() }
109 }
110 pub fn activate<'a>(&'a mut self) -> OutputBuilderSession<'a, T, CB> {
112 OutputBuilderSession {
113 session: self.output.activate(),
114 builder: &mut self.builder,
115 }
116 }
117}
118
119pub struct OutputBuilderSession<'a, T: Timestamp, CB: ContainerBuilder> {
121 session: crate::dataflow::channels::pushers::OutputSession<'a, T, CB::Container>,
122 builder: &'a mut CB,
123}
124
125impl<'a, T: Timestamp, CB: ContainerBuilder> OutputBuilderSession<'a, T, CB> {
126 #[inline]
128 pub fn output_index(&self) -> usize { self.session.output_index()}
129
130 pub fn session_with_builder<'b, CT: CapabilityTrait<T>>(&'b mut self, capability: &'b CT) -> Session<'a, 'b, T, CB, CT> where 'a: 'b {
135 debug_assert!(self.session.valid(capability));
136 Session {
137 buffer: self,
138 capability,
139 }
140 }
141}
142
143impl<'a, T: Timestamp, C: Container> OutputBuilderSession<'a, T, CapacityContainerBuilder<C>> {
144 pub fn session<'b, CT: CapabilityTrait<T>>(&'b mut self, capability: &'b CT) -> Session<'a, 'b, T, CapacityContainerBuilder<C>, CT> where 'a: 'b {
149 debug_assert!(self.session.valid(capability));
150 Session {
151 buffer: self,
152 capability,
153 }
154 }
155}
156
157pub struct Session<'a: 'b, 'b, T: Timestamp, CB: ContainerBuilder, CT: CapabilityTrait<T>> {
159 buffer: &'b mut OutputBuilderSession<'a, T, CB>,
160 capability: &'b CT,
161}
162
163impl<'a: 'b, 'b, T: Timestamp, CB: ContainerBuilder, CT: CapabilityTrait<T>> Session<'a, 'b, T, CB, CT> {
164
165 pub fn builder(&mut self) -> &mut CB { &mut self.buffer.builder }
167
168 #[inline] pub fn give<D>(&mut self, data: D) where CB: PushInto<D> {
170 self.buffer.builder.push_into(data);
171 self.extract_and_send();
172 }
173 #[inline] pub fn give_iterator<I>(&mut self, iter: I) where I: Iterator, CB: PushInto<I::Item> {
175 for item in iter { self.buffer.builder.push_into(item); }
176 self.extract_and_send();
177 }
178 #[inline] pub fn give_container(&mut self, container: &mut CB::Container) {
180 self.buffer.session.give(&self.capability, container);
181 }
182 #[inline] pub fn give_containers<'c>(&mut self, containers: impl Iterator<Item = &'c mut CB::Container>) {
184 for container in containers { self.buffer.session.give(&self.capability, container); }
185 }
186
187 pub fn extract_and_send(&mut self) {
189 while let Some(container) = self.buffer.builder.extract() {
190 self.buffer.session.give(&self.capability, container);
191 }
192 }
193 pub fn flush(&mut self) {
195 while let Some(container) = self.buffer.builder.finish() {
196 self.buffer.session.give(&self.capability, container);
197 }
198 }
199}
200
201impl<'a: 'b, 'b, T: Timestamp, CB: ContainerBuilder, CT: CapabilityTrait<T>> Drop for Session<'a, 'b, T, CB, CT> {
202 fn drop(&mut self) { self.flush() }
203}