@@ -7,27 +7,11 @@ use std::collections::VecDeque;
77/// A container transferring data through dataflow edges
88///
99/// A container stores a number of elements and thus is able to describe it length (`len()`) and
10- /// whether it is empty (`is_empty()`). It supports removing all elements (`clear`).
10+ /// whether it is empty (`is_empty()`).
1111///
1212/// A container must implement default. The default implementation is not required to allocate
1313/// memory for variable-length components.
14- ///
15- /// We require the container to be cloneable to enable efficient copies when providing references
16- /// of containers to operators. Care must be taken that the type's `clone_from` implementation
17- /// is efficient (which is not necessarily the case when deriving `Clone`.)
18- pub trait Container : Default {
19- /// The type of elements when reading non-destructively from the container.
20- type ItemRef < ' a > where Self : ' a ;
21-
22- /// The type of elements when draining the container.
23- type Item < ' a > where Self : ' a ;
24-
25- /// Push `item` into self
26- #[ inline]
27- fn push < T > ( & mut self , item : T ) where Self : PushInto < T > {
28- self . push_into ( item)
29- }
30-
14+ pub trait ProgressContainer : Default {
3115 /// The number of elements in this container
3216 ///
3317 /// This number is used in progress tracking to confirm the receipt of some number
@@ -37,9 +21,27 @@ pub trait Container: Default {
3721 fn len ( & self ) -> usize ;
3822
3923 /// Determine if the container contains any elements, corresponding to `len() == 0`.
24+ #[ inline( always) ]
4025 fn is_empty ( & self ) -> bool {
4126 self . len ( ) == 0
4227 }
28+ }
29+
30+ /// A container that can reveal its contents through iterating by reference and draining.
31+ ///
32+ /// It supports removing all elements (`clear`).
33+ pub trait Container : ProgressContainer {
34+ /// The type of elements when reading non-destructively from the container.
35+ type ItemRef < ' a > where Self : ' a ;
36+
37+ /// The type of elements when draining the container.
38+ type Item < ' a > where Self : ' a ;
39+
40+ /// Push `item` into self
41+ #[ inline]
42+ fn push < T > ( & mut self , item : T ) where Self : PushInto < T > {
43+ self . push_into ( item)
44+ }
4345
4446 /// Remove all contents from `self` while retaining allocated memory.
4547 /// After calling `clear`, `is_empty` must return `true` and `len` 0.
@@ -102,7 +104,7 @@ pub trait PushInto<T> {
102104/// decide to represent a push order for `extract` and `finish`, or not.
103105pub trait ContainerBuilder : Default + ' static {
104106 /// The container type we're building.
105- type Container : Container + Clone + ' static ;
107+ type Container : ProgressContainer + Clone + ' static ;
106108 /// Extract assembled containers, potentially leaving unfinished data behind. Can
107109 /// be called repeatedly, for example while the caller can send data.
108110 ///
@@ -118,6 +120,7 @@ pub trait ContainerBuilder: Default + 'static {
118120 where
119121 Self : for < ' a > PushInto < <Self :: Container as Container >:: Item < ' a > > ,
120122 I : for < ' a > FnMut ( & <Self :: Container as Container >:: Item < ' a > ) -> usize ,
123+ Self :: Container : Container ,
121124 {
122125 for datum in container. drain ( ) {
123126 let index = index ( & datum) ;
@@ -142,6 +145,35 @@ pub trait ContainerBuilder: Default + 'static {
142145/// If you have any questions about this trait you are best off not implementing it.
143146pub trait LengthPreservingContainerBuilder : ContainerBuilder { }
144147
148+ /// A container builder that never produces any outputs, and can be used to pass through data in
149+ /// operators.
150+ #[ derive( Debug , Clone ) ]
151+ pub struct PassthroughContainerBuilder < C > ( std:: marker:: PhantomData < C > ) ;
152+
153+ impl < C > Default for PassthroughContainerBuilder < C > {
154+ #[ inline( always) ]
155+ fn default ( ) -> Self {
156+ PassthroughContainerBuilder ( std:: marker:: PhantomData )
157+ }
158+ }
159+
160+ impl < C > ContainerBuilder for PassthroughContainerBuilder < C >
161+ where
162+ C : ProgressContainer + Clone + ' static ,
163+ {
164+ type Container = C ;
165+
166+ #[ inline( always) ]
167+ fn extract ( & mut self ) -> Option < & mut Self :: Container > {
168+ None
169+ }
170+
171+ #[ inline( always) ]
172+ fn finish ( & mut self ) -> Option < & mut Self :: Container > {
173+ None
174+ }
175+ }
176+
145177/// A default container builder that uses length and preferred capacity to chunk data.
146178///
147179/// Maintains a single empty allocation between [`Self::push_into`] and [`Self::extract`], but not
@@ -165,7 +197,7 @@ impl<T, C: SizableContainer + PushInto<T>> PushInto<T> for CapacityContainerBuil
165197 self . current . ensure_capacity ( & mut self . empty ) ;
166198
167199 // Push item
168- self . current . push ( item) ;
200+ self . current . push_into ( item) ;
169201
170202 // Maybe flush
171203 if self . current . at_capacity ( ) {
@@ -199,18 +231,18 @@ impl<C: Container + Clone + 'static> ContainerBuilder for CapacityContainerBuild
199231
200232impl < C : Container + Clone + ' static > LengthPreservingContainerBuilder for CapacityContainerBuilder < C > { }
201233
234+ impl < T > ProgressContainer for Vec < T > {
235+ #[ inline( always) ]
236+ fn len ( & self ) -> usize { Vec :: len ( self ) }
237+
238+ #[ inline( always) ]
239+ fn is_empty ( & self ) -> bool { Vec :: is_empty ( self ) }
240+ }
241+
202242impl < T > Container for Vec < T > {
203243 type ItemRef < ' a > = & ' a T where T : ' a ;
204244 type Item < ' a > = T where T : ' a ;
205245
206- fn len ( & self ) -> usize {
207- Vec :: len ( self )
208- }
209-
210- fn is_empty ( & self ) -> bool {
211- Vec :: is_empty ( self )
212- }
213-
214246 fn clear ( & mut self ) { Vec :: clear ( self ) }
215247
216248 type Iter < ' a > = std:: slice:: Iter < ' a , T > where Self : ' a ;
@@ -268,20 +300,20 @@ mod rc {
268300 use std:: ops:: Deref ;
269301 use std:: rc:: Rc ;
270302
271- use crate :: Container ;
303+ use crate :: { Container , ProgressContainer } ;
304+
305+ impl < T : ProgressContainer > ProgressContainer for Rc < T > {
306+ #[ inline( always) ]
307+ fn len ( & self ) -> usize { std:: ops:: Deref :: deref ( self ) . len ( ) }
308+
309+ #[ inline( always) ]
310+ fn is_empty ( & self ) -> bool { std:: ops:: Deref :: deref ( self ) . is_empty ( ) }
311+ }
272312
273313 impl < T : Container > Container for Rc < T > {
274314 type ItemRef < ' a > = T :: ItemRef < ' a > where Self : ' a ;
275315 type Item < ' a > = T :: ItemRef < ' a > where Self : ' a ;
276316
277- fn len ( & self ) -> usize {
278- std:: ops:: Deref :: deref ( self ) . len ( )
279- }
280-
281- fn is_empty ( & self ) -> bool {
282- std:: ops:: Deref :: deref ( self ) . is_empty ( )
283- }
284-
285317 fn clear ( & mut self ) {
286318 // Try to reuse the allocation if possible
287319 if let Some ( inner) = Rc :: get_mut ( self ) {
@@ -309,20 +341,20 @@ mod arc {
309341 use std:: ops:: Deref ;
310342 use std:: sync:: Arc ;
311343
312- use crate :: Container ;
344+ use crate :: { Container , ProgressContainer } ;
345+
346+ impl < T : ProgressContainer > ProgressContainer for Arc < T > {
347+ #[ inline( always) ]
348+ fn len ( & self ) -> usize { std:: ops:: Deref :: deref ( self ) . len ( ) }
349+
350+ #[ inline( always) ]
351+ fn is_empty ( & self ) -> bool { std:: ops:: Deref :: deref ( self ) . is_empty ( ) }
352+ }
313353
314354 impl < T : Container > Container for Arc < T > {
315355 type ItemRef < ' a > = T :: ItemRef < ' a > where Self : ' a ;
316356 type Item < ' a > = T :: ItemRef < ' a > where Self : ' a ;
317357
318- fn len ( & self ) -> usize {
319- std:: ops:: Deref :: deref ( self ) . len ( )
320- }
321-
322- fn is_empty ( & self ) -> bool {
323- std:: ops:: Deref :: deref ( self ) . is_empty ( )
324- }
325-
326358 fn clear ( & mut self ) {
327359 // Try to reuse the allocation if possible
328360 if let Some ( inner) = Arc :: get_mut ( self ) {
0 commit comments