File tree 4 files changed +75
-0
lines changed
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 5
5
6
6
pub mod vec_deque;
7
7
pub mod hash_map;
8
+ pub mod hash_set;
8
9
pub mod btree_map;
9
10
10
11
pub use vec_deque:: VecDeque ;
11
12
pub use hash_map:: HashMap ;
13
+ pub use hash_set:: HashSet ;
12
14
pub use btree_map:: BTreeMap ;
You can’t perform that action at this time.
0 commit comments