3
3
//! as required by the query system.
4
4
5
5
use rustc_hash:: { FxHashMap , FxHashSet } ;
6
- use smallvec:: SmallVec ;
7
6
use std:: {
8
- borrow:: Borrow ,
7
+ borrow:: { Borrow , BorrowMut } ,
9
8
collections:: hash_map:: Entry ,
10
9
hash:: Hash ,
11
10
iter:: { Product , Sum } ,
@@ -14,7 +13,7 @@ use std::{
14
13
15
14
use crate :: {
16
15
fingerprint:: Fingerprint ,
17
- stable_hasher:: { HashStable , StableHasher , StableOrd , ToStableHashKey } ,
16
+ stable_hasher:: { HashStable , StableCompare , StableHasher , ToStableHashKey } ,
18
17
} ;
19
18
20
19
/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
@@ -134,36 +133,76 @@ impl<'a, T: Copy + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
134
133
}
135
134
}
136
135
137
- impl < T : Ord , I : Iterator < Item = T > > UnordItems < T , I > {
136
+ impl < T , I : Iterator < Item = T > > UnordItems < T , I > {
137
+ #[ inline]
138
138
pub fn into_sorted < HCX > ( self , hcx : & HCX ) -> Vec < T >
139
139
where
140
140
T : ToStableHashKey < HCX > ,
141
141
{
142
- let mut items: Vec < T > = self . 0 . collect ( ) ;
143
- items. sort_by_cached_key ( |x| x. to_stable_hash_key ( hcx) ) ;
144
- items
142
+ self . collect_sorted ( hcx, true )
145
143
}
146
144
147
145
#[ inline]
148
146
pub fn into_sorted_stable_ord ( self ) -> Vec < T >
149
147
where
150
- T : Ord + StableOrd ,
148
+ T : StableCompare ,
149
+ {
150
+ self . collect_stable_ord_by_key ( |x| x)
151
+ }
152
+
153
+ #[ inline]
154
+ pub fn into_sorted_stable_ord_by_key < K , C > ( self , project_to_key : C ) -> Vec < T >
155
+ where
156
+ K : StableCompare ,
157
+ C : for < ' a > Fn ( & ' a T ) -> & ' a K ,
158
+ {
159
+ self . collect_stable_ord_by_key ( project_to_key)
160
+ }
161
+
162
+ pub fn collect_sorted < HCX , C > ( self , hcx : & HCX , cache_sort_key : bool ) -> C
163
+ where
164
+ T : ToStableHashKey < HCX > ,
165
+ C : FromIterator < T > + BorrowMut < [ T ] > ,
151
166
{
152
- let mut items: Vec < T > = self . 0 . collect ( ) ;
153
- if !T :: CAN_USE_UNSTABLE_SORT {
154
- items. sort ( ) ;
155
- } else {
156
- items. sort_unstable ( )
167
+ let mut items: C = self . 0 . collect ( ) ;
168
+
169
+ let slice = items. borrow_mut ( ) ;
170
+ if slice. len ( ) > 1 {
171
+ if cache_sort_key {
172
+ slice. sort_by_cached_key ( |x| x. to_stable_hash_key ( hcx) ) ;
173
+ } else {
174
+ slice. sort_by_key ( |x| x. to_stable_hash_key ( hcx) ) ;
175
+ }
157
176
}
177
+
158
178
items
159
179
}
160
180
161
- pub fn into_sorted_small_vec < HCX , const LEN : usize > ( self , hcx : & HCX ) -> SmallVec < [ T ; LEN ] >
181
+ pub fn collect_stable_ord_by_key < K , C , P > ( self , project_to_key : P ) -> C
162
182
where
163
- T : ToStableHashKey < HCX > ,
183
+ K : StableCompare ,
184
+ P : for < ' a > Fn ( & ' a T ) -> & ' a K ,
185
+ C : FromIterator < T > + BorrowMut < [ T ] > ,
164
186
{
165
- let mut items: SmallVec < [ T ; LEN ] > = self . 0 . collect ( ) ;
166
- items. sort_by_cached_key ( |x| x. to_stable_hash_key ( hcx) ) ;
187
+ let mut items: C = self . 0 . collect ( ) ;
188
+
189
+ let slice = items. borrow_mut ( ) ;
190
+ if slice. len ( ) > 1 {
191
+ if !K :: CAN_USE_UNSTABLE_SORT {
192
+ slice. sort_by ( |a, b| {
193
+ let a_key = project_to_key ( a) ;
194
+ let b_key = project_to_key ( b) ;
195
+ a_key. stable_cmp ( b_key)
196
+ } ) ;
197
+ } else {
198
+ slice. sort_unstable_by ( |a, b| {
199
+ let a_key = project_to_key ( a) ;
200
+ let b_key = project_to_key ( b) ;
201
+ a_key. stable_cmp ( b_key)
202
+ } ) ;
203
+ }
204
+ }
205
+
167
206
items
168
207
}
169
208
}
@@ -268,16 +307,30 @@ impl<V: Eq + Hash> UnordSet<V> {
268
307
}
269
308
270
309
/// Returns the items of this set in stable sort order (as defined by
271
- /// `StableOrd`). This method is much more efficient than
310
+ /// `StableCompare`). This method is much more efficient than
311
+ /// `into_sorted` because it does not need to transform keys to their
312
+ /// `ToStableHashKey` equivalent.
313
+ #[ inline]
314
+ pub fn to_sorted_stable_ord ( & self ) -> Vec < & V >
315
+ where
316
+ V : StableCompare ,
317
+ {
318
+ let mut items: Vec < & V > = self . inner . iter ( ) . collect ( ) ;
319
+ items. sort_unstable_by ( |a, b| a. stable_cmp ( * b) ) ;
320
+ items
321
+ }
322
+
323
+ /// Returns the items of this set in stable sort order (as defined by
324
+ /// `StableCompare`). This method is much more efficient than
272
325
/// `into_sorted` because it does not need to transform keys to their
273
326
/// `ToStableHashKey` equivalent.
274
327
#[ inline]
275
- pub fn to_sorted_stable_ord ( & self ) -> Vec < V >
328
+ pub fn into_sorted_stable_ord ( self ) -> Vec < V >
276
329
where
277
- V : Ord + StableOrd + Clone ,
330
+ V : StableCompare ,
278
331
{
279
- let mut items: Vec < V > = self . inner . iter ( ) . cloned ( ) . collect ( ) ;
280
- items. sort_unstable ( ) ;
332
+ let mut items: Vec < V > = self . inner . into_iter ( ) . collect ( ) ;
333
+ items. sort_unstable_by ( V :: stable_cmp ) ;
281
334
items
282
335
}
283
336
@@ -483,16 +536,16 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
483
536
to_sorted_vec ( hcx, self . inner . iter ( ) , cache_sort_key, |& ( k, _) | k)
484
537
}
485
538
486
- /// Returns the entries of this map in stable sort order (as defined by `StableOrd `).
539
+ /// Returns the entries of this map in stable sort order (as defined by `StableCompare `).
487
540
/// This method can be much more efficient than `into_sorted` because it does not need
488
541
/// to transform keys to their `ToStableHashKey` equivalent.
489
542
#[ inline]
490
- pub fn to_sorted_stable_ord ( & self ) -> Vec < ( K , & V ) >
543
+ pub fn to_sorted_stable_ord ( & self ) -> Vec < ( & K , & V ) >
491
544
where
492
- K : Ord + StableOrd + Copy ,
545
+ K : StableCompare ,
493
546
{
494
- let mut items: Vec < ( K , & V ) > = self . inner . iter ( ) . map ( | ( & k , v ) | ( k , v ) ) . collect ( ) ;
495
- items. sort_unstable_by_key ( | & ( k , _) | k ) ;
547
+ let mut items: Vec < _ > = self . inner . iter ( ) . collect ( ) ;
548
+ items. sort_unstable_by ( | ( a , _) , ( b , _ ) | a . stable_cmp ( * b ) ) ;
496
549
items
497
550
}
498
551
@@ -510,6 +563,19 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
510
563
to_sorted_vec ( hcx, self . inner . into_iter ( ) , cache_sort_key, |( k, _) | k)
511
564
}
512
565
566
+ /// Returns the entries of this map in stable sort order (as defined by `StableCompare`).
567
+ /// This method can be much more efficient than `into_sorted` because it does not need
568
+ /// to transform keys to their `ToStableHashKey` equivalent.
569
+ #[ inline]
570
+ pub fn into_sorted_stable_ord ( self ) -> Vec < ( K , V ) >
571
+ where
572
+ K : StableCompare ,
573
+ {
574
+ let mut items: Vec < ( K , V ) > = self . inner . into_iter ( ) . collect ( ) ;
575
+ items. sort_unstable_by ( |a, b| a. 0 . stable_cmp ( & b. 0 ) ) ;
576
+ items
577
+ }
578
+
513
579
/// Returns the values of this map in stable sort order (as defined by K's
514
580
/// `ToStableHashKey` implementation).
515
581
///
0 commit comments