File tree Expand file tree Collapse file tree 4 files changed +75
-0
lines changed Expand file tree Collapse file tree 4 files changed +75
-0
lines changed Original file line number Diff line number Diff line change 1+ use std:: pin:: Pin ;
2+ use std:: hash:: { Hash , BuildHasher } ;
3+ use std:: collections:: HashSet ;
4+
5+ use crate :: prelude:: * ;
6+ use crate :: stream:: { Extend , IntoStream } ;
7+
8+ impl < T , H > Extend < T > for HashSet < T , H >
9+ where T : Eq + Hash ,
10+ H : BuildHasher + Default {
11+ fn stream_extend < ' a , S : IntoStream < Item = T > + ' a > (
12+ & ' a mut self ,
13+ stream : S ,
14+ ) -> Pin < Box < dyn Future < Output = ( ) > + ' a > > {
15+ // The Extend impl for HashSet in the standard library delegates to the internal HashMap.
16+ // Thus, this impl is just a copy of the async Extend impl for HashMap in this crate.
17+
18+ let stream = stream. into_stream ( ) ;
19+
20+ // The following is adapted from the hashbrown source code:
21+ // https://github.com/rust-lang/hashbrown/blob/d1ad4fc3aae2ade446738eea512e50b9e863dd0c/src/map.rs#L2470-L2491
22+ //
23+ // Keys may be already present or show multiple times in the stream. Reserve the entire
24+ // hint lower bound if the map is empty. Otherwise reserve half the hint (rounded up), so
25+ // the map will only resize twice in the worst case.
26+
27+ //TODO: Add this back in when size_hint is added to Stream/StreamExt
28+ //let reserve = if self.is_empty() {
29+ // stream.size_hint().0
30+ //} else {
31+ // (stream.size_hint().0 + 1) / 2
32+ //};
33+ //self.reserve(reserve);
34+
35+ Box :: pin ( stream. for_each ( move |item| {
36+ self . insert ( item) ;
37+ } ) )
38+ }
39+ }
Original file line number Diff line number Diff line change 1+ use std:: pin:: Pin ;
2+ use std:: hash:: { Hash , BuildHasher } ;
3+ use std:: collections:: HashSet ;
4+
5+ use crate :: stream:: { Extend , FromStream , IntoStream } ;
6+
7+ impl < T , H > FromStream < T > for HashSet < T , H >
8+ where T : Eq + Hash ,
9+ H : BuildHasher + Default {
10+ #[ inline]
11+ fn from_stream < ' a , S : IntoStream < Item = T > > (
12+ stream : S ,
13+ ) -> Pin < Box < dyn core:: future:: Future < Output = Self > + ' a > >
14+ where
15+ <S as IntoStream >:: IntoStream : ' a ,
16+ {
17+ let stream = stream. into_stream ( ) ;
18+
19+ Box :: pin ( async move {
20+ pin_utils:: pin_mut!( stream) ;
21+
22+ let mut out = HashSet :: with_hasher ( Default :: default ( ) ) ;
23+ out. stream_extend ( stream) . await ;
24+ out
25+ } )
26+ }
27+ }
Original file line number Diff line number Diff line change 1+ //! The Rust hash set, implemented as a `HashMap` where the value is `()`.
2+
3+ mod extend;
4+ mod from_stream;
5+
6+ #[ doc( inline) ]
7+ pub use std:: collections:: HashSet ;
Original file line number Diff line number Diff line change 55
66pub mod vec_deque;
77pub mod hash_map;
8+ pub mod hash_set;
89pub mod btree_map;
910
1011pub use vec_deque:: VecDeque ;
1112pub use hash_map:: HashMap ;
13+ pub use hash_set:: HashSet ;
1214pub use btree_map:: BTreeMap ;
You can’t perform that action at this time.
0 commit comments