@@ -6,21 +6,25 @@ use std::collections::VecDeque;
66
77/// A type representing progress, with an update count.
88///
9- /// It describes its update count (`count()`) and whether it is empty (`is_empty()`) .
9+ /// It describes its update count (`count()`).
1010///
1111/// We require [`Default`] for convenience purposes.
12- pub trait WithProgress : Default {
12+ pub trait Container : Default {
1313 /// The number of elements in this container
1414 ///
1515 /// This number is used in progress tracking to confirm the receipt of some number
1616 /// of outstanding records, and it is highly load bearing. The main restriction is
17- /// imposed on the [`CountPreservingContainerBuilder `] trait, whose implementors
17+ /// imposed on the [`LengthPreservingContainerBuilder `] trait, whose implementors
1818 /// must preserve the number of items.
1919 fn count ( & self ) -> usize ;
20+
21+ /// Remove all contents from `self` while retaining allocated memory.
22+ /// After calling `clear`, `is_empty` must return `true` and `len` 0.
23+ fn clear ( & mut self ) ;
2024}
2125
2226/// A container that can reveal its contents through iterating by reference and draining.
23- pub trait IterableContainer : WithProgress {
27+ pub trait IterContainer : Container {
2428 /// The type of elements when reading non-destructively from the container.
2529 type ItemRef < ' a > where Self : ' a ;
2630
@@ -42,7 +46,7 @@ pub trait IterableContainer: WithProgress {
4246}
4347
4448/// A container that can be sized and reveals its capacity.
45- pub trait SizableContainer : WithProgress {
49+ pub trait SizableContainer : Container {
4650 /// Indicates that the container is "full" and should be shipped.
4751 fn at_capacity ( & self ) -> bool ;
4852 /// Restores `self` to its desired capacity, if it has one.
@@ -84,7 +88,7 @@ pub trait PushInto<T> {
8488/// decide to represent a push order for `extract` and `finish`, or not.
8589pub trait ContainerBuilder : Default + ' static {
8690 /// The container type we're building.
87- type Container : WithProgress + Default + Clone + ' static ;
91+ type Container : Container + Clone + ' static ;
8892 /// Extract assembled containers, potentially leaving unfinished data behind. Can
8993 /// be called repeatedly, for example while the caller can send data.
9094 ///
@@ -98,14 +102,15 @@ pub trait ContainerBuilder: Default + 'static {
98102 /// Partitions `container` among `builders`, using the function `index` to direct items.
99103 fn partition < I > ( container : & mut Self :: Container , builders : & mut [ Self ] , mut index : I )
100104 where
101- Self : for < ' a > PushInto < <Self :: Container as IterableContainer >:: Item < ' a > > ,
102- I : for < ' a > FnMut ( & <Self :: Container as IterableContainer >:: Item < ' a > ) -> usize ,
103- Self :: Container : IterableContainer ,
105+ Self : for < ' a > PushInto < <Self :: Container as IterContainer >:: Item < ' a > > ,
106+ I : for < ' a > FnMut ( & <Self :: Container as IterContainer >:: Item < ' a > ) -> usize ,
107+ Self :: Container : IterContainer ,
104108 {
105109 for datum in container. drain ( ) {
106110 let index = index ( & datum) ;
107111 builders[ index] . push_into ( datum) ;
108112 }
113+ container. clear ( ) ;
109114 }
110115
111116 /// Indicates a good moment to release resources.
@@ -122,7 +127,7 @@ pub trait ContainerBuilder: Default + 'static {
122127/// Specifically, the sum of lengths of all extracted and finished containers must equal the
123128/// number of times that `push_into` is called on the container builder.
124129/// If you have any questions about this trait you are best off not implementing it.
125- pub trait CountPreservingContainerBuilder : ContainerBuilder { }
130+ pub trait LengthPreservingContainerBuilder : ContainerBuilder { }
126131
127132/// A container builder that never produces any outputs, and can be used to pass through data in
128133/// operators.
@@ -136,7 +141,7 @@ impl<C> Default for PassthroughContainerBuilder<C> {
136141 }
137142}
138143
139- impl < C : WithProgress + Clone + ' static > ContainerBuilder for PassthroughContainerBuilder < C >
144+ impl < C : Container + Clone + ' static > ContainerBuilder for PassthroughContainerBuilder < C >
140145{
141146 type Container = C ;
142147
@@ -183,7 +188,7 @@ impl<T, C: SizableContainer + PushInto<T>> PushInto<T> for CapacityContainerBuil
183188 }
184189}
185190
186- impl < C : WithProgress + Clone + ' static > ContainerBuilder for CapacityContainerBuilder < C > {
191+ impl < C : Container + Clone + ' static > ContainerBuilder for CapacityContainerBuilder < C > {
187192 type Container = C ;
188193
189194 #[ inline]
@@ -206,9 +211,14 @@ impl<C: WithProgress + Clone + 'static> ContainerBuilder for CapacityContainerBu
206211 }
207212}
208213
209- impl < C : WithProgress + SizableContainer + Clone + ' static > CountPreservingContainerBuilder for CapacityContainerBuilder < C > { }
214+ impl < C : Container + SizableContainer + Clone + ' static > LengthPreservingContainerBuilder for CapacityContainerBuilder < C > { }
215+
216+ impl < T > Container for Vec < T > {
217+ #[ inline( always) ] fn count ( & self ) -> usize { Vec :: len ( self ) }
218+ #[ inline( always) ] fn clear ( & mut self ) { Vec :: clear ( self ) }
219+ }
210220
211- impl < T > IterableContainer for Vec < T > {
221+ impl < T > IterContainer for Vec < T > {
212222 type ItemRef < ' a > = & ' a T where T : ' a ;
213223 type Item < ' a > = T where T : ' a ;
214224 type Iter < ' a > = std:: slice:: Iter < ' a , T > where Self : ' a ;
@@ -266,9 +276,22 @@ mod rc {
266276 use std:: ops:: Deref ;
267277 use std:: rc:: Rc ;
268278
269- use crate :: IterableContainer ;
279+ use crate :: { Container , IterContainer } ;
280+
281+ impl < T : Container > Container for Rc < T > {
282+ #[ inline( always) ] fn count ( & self ) -> usize { self . as_ref ( ) . count ( ) }
283+ #[ inline( always) ] fn clear ( & mut self ) {
284+ // Try to reuse the allocation if possible
285+ if let Some ( inner) = Rc :: get_mut ( self ) {
286+ inner. clear ( ) ;
287+ } else {
288+ * self = Self :: default ( ) ;
289+ }
290+ }
291+ }
292+
270293
271- impl < T : IterableContainer > IterableContainer for Rc < T > {
294+ impl < T : IterContainer > IterContainer for Rc < T > {
272295 type ItemRef < ' a > = T :: ItemRef < ' a > where Self : ' a ;
273296 type Item < ' a > = T :: ItemRef < ' a > where Self : ' a ;
274297 type Iter < ' a > = T :: Iter < ' a > where Self : ' a ;
@@ -289,9 +312,21 @@ mod arc {
289312 use std:: ops:: Deref ;
290313 use std:: sync:: Arc ;
291314
292- use crate :: IterableContainer ;
315+ use crate :: { Container , IterContainer } ;
316+
317+ impl < T : Container > Container for std:: sync:: Arc < T > {
318+ #[ inline( always) ] fn count ( & self ) -> usize { self . as_ref ( ) . count ( ) }
319+ #[ inline( always) ] fn clear ( & mut self ) {
320+ // Try to reuse the allocation if possible
321+ if let Some ( inner) = Arc :: get_mut ( self ) {
322+ inner. clear ( ) ;
323+ } else {
324+ * self = Self :: default ( ) ;
325+ }
326+ }
327+ }
293328
294- impl < T : IterableContainer > IterableContainer for Arc < T > {
329+ impl < T : IterContainer > IterContainer for Arc < T > {
295330 type ItemRef < ' a > = T :: ItemRef < ' a > where Self : ' a ;
296331 type Item < ' a > = T :: ItemRef < ' a > where Self : ' a ;
297332 type Iter < ' a > = T :: Iter < ' a > where Self : ' a ;
@@ -328,15 +363,3 @@ pub mod buffer {
328363 }
329364 }
330365}
331-
332- impl < T > WithProgress for Vec < T > {
333- #[ inline( always) ] fn count ( & self ) -> usize { self . len ( ) }
334- }
335-
336- impl < T : WithProgress > WithProgress for std:: rc:: Rc < T > {
337- #[ inline( always) ] fn count ( & self ) -> usize { self . as_ref ( ) . count ( ) }
338- }
339-
340- impl < T : WithProgress > WithProgress for std:: sync:: Arc < T > {
341- #[ inline( always) ] fn count ( & self ) -> usize { self . as_ref ( ) . count ( ) }
342- }
0 commit comments