Skip to content

Commit 41942fa

Browse files
committed
SsoHashSet reimplemented as a wrapper on top of SsoHashMap
SsoHashSet::replace had to be removed because it requires missing API from SsoHashMap. It's not a widely used function, so I think it's ok to omit it for now. EitherIter moved into its own file. Also sprinkled code with #[inline] attributes where appropriate.
1 parent 0600b17 commit 41942fa

File tree

4 files changed

+158
-228
lines changed

4 files changed

+158
-228
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::fmt;
2+
use std::iter::ExactSizeIterator;
3+
use std::iter::FusedIterator;
4+
use std::iter::Iterator;
5+
6+
/// Iterator which may contain instance of
7+
/// one of two specific implementations.
8+
///
9+
/// Note: For most methods providing custom
10+
/// implementation may margianlly
11+
/// improve performance by avoiding
12+
/// doing Left/Right match on every step
13+
/// and doing it only once instead.
14+
#[derive(Clone)]
15+
pub enum EitherIter<L, R> {
16+
Left(L),
17+
Right(R),
18+
}
19+
20+
impl<L, R> Iterator for EitherIter<L, R>
21+
where
22+
L: Iterator,
23+
R: Iterator<Item = L::Item>,
24+
{
25+
type Item = L::Item;
26+
27+
fn next(&mut self) -> Option<Self::Item> {
28+
match self {
29+
EitherIter::Left(l) => l.next(),
30+
EitherIter::Right(r) => r.next(),
31+
}
32+
}
33+
34+
fn size_hint(&self) -> (usize, Option<usize>) {
35+
match self {
36+
EitherIter::Left(l) => l.size_hint(),
37+
EitherIter::Right(r) => r.size_hint(),
38+
}
39+
}
40+
}
41+
42+
impl<L, R> ExactSizeIterator for EitherIter<L, R>
43+
where
44+
L: ExactSizeIterator,
45+
R: ExactSizeIterator,
46+
EitherIter<L, R>: Iterator,
47+
{
48+
fn len(&self) -> usize {
49+
match self {
50+
EitherIter::Left(l) => l.len(),
51+
EitherIter::Right(r) => r.len(),
52+
}
53+
}
54+
}
55+
56+
impl<L, R> FusedIterator for EitherIter<L, R>
57+
where
58+
L: FusedIterator,
59+
R: FusedIterator,
60+
EitherIter<L, R>: Iterator,
61+
{
62+
}
63+
64+
impl<L, R> fmt::Debug for EitherIter<L, R>
65+
where
66+
L: fmt::Debug,
67+
R: fmt::Debug,
68+
{
69+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70+
match self {
71+
EitherIter::Left(l) => l.fmt(f),
72+
EitherIter::Right(r) => r.fmt(f),
73+
}
74+
}
75+
}

compiler/rustc_data_structures/src/sso/map.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::EitherIter;
1+
use super::either_iter::EitherIter;
22
use crate::fx::FxHashMap;
33
use arrayvec::ArrayVec;
44
use std::borrow::Borrow;
@@ -32,6 +32,7 @@ pub enum SsoHashMap<K, V> {
3232

3333
impl<K, V> SsoHashMap<K, V> {
3434
/// Creates an empty `SsoHashMap`.
35+
#[inline]
3536
pub fn new() -> Self {
3637
SsoHashMap::Array(ArrayVec::new())
3738
}
@@ -81,13 +82,15 @@ impl<K, V> SsoHashMap<K, V> {
8182

8283
/// An iterator visiting all key-value pairs in arbitrary order.
8384
/// The iterator element type is `(&'a K, &'a V)`.
84-
pub fn iter(&self) -> impl Iterator<Item = (&'_ K, &'_ V)> {
85+
#[inline]
86+
pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
8587
self.into_iter()
8688
}
8789

8890
/// An iterator visiting all key-value pairs in arbitrary order,
8991
/// with mutable references to the values.
9092
/// The iterator element type is `(&'a K, &'a mut V)`.
93+
#[inline]
9194
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&'_ K, &'_ mut V)> {
9295
self.into_iter()
9396
}
@@ -319,12 +322,14 @@ impl<K: Eq + Hash, V> SsoHashMap<K, V> {
319322
}
320323

321324
/// Gets the given key's corresponding entry in the map for in-place manipulation.
325+
#[inline]
322326
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
323327
Entry { ssomap: self, key }
324328
}
325329
}
326330

327331
impl<K, V> Default for SsoHashMap<K, V> {
332+
#[inline]
328333
fn default() -> Self {
329334
Self::new()
330335
}
@@ -348,6 +353,7 @@ impl<K: Eq + Hash, V> Extend<(K, V)> for SsoHashMap<K, V> {
348353
}
349354
}
350355

356+
#[inline]
351357
fn extend_one(&mut self, (k, v): (K, V)) {
352358
self.insert(k, v);
353359
}
@@ -375,10 +381,12 @@ where
375381
self.extend(iter.into_iter().map(|(k, v)| (k.clone(), v.clone())))
376382
}
377383

384+
#[inline]
378385
fn extend_one(&mut self, (&k, &v): (&'a K, &'a V)) {
379386
self.insert(k, v);
380387
}
381388

389+
#[inline]
382390
fn extend_reserve(&mut self, additional: usize) {
383391
Extend::<(K, V)>::extend_reserve(self, additional)
384392
}
@@ -400,12 +408,14 @@ impl<K, V> IntoIterator for SsoHashMap<K, V> {
400408
}
401409

402410
/// adapts Item of array reference iterator to Item of hashmap reference iterator.
411+
#[inline(always)]
403412
fn adapt_array_ref_it<K, V>(pair: &'a (K, V)) -> (&'a K, &'a V) {
404413
let (a, b) = pair;
405414
(a, b)
406415
}
407416

408417
/// adapts Item of array mut reference iterator to Item of hashmap mut reference iterator.
418+
#[inline(always)]
409419
fn adapt_array_mut_it<K, V>(pair: &'a mut (K, V)) -> (&'a K, &'a mut V) {
410420
let (a, b) = pair;
411421
(a, b)
@@ -464,6 +474,7 @@ where
464474
{
465475
type Output = V;
466476

477+
#[inline]
467478
fn index(&self, key: &Q) -> &V {
468479
self.get(key).expect("no entry found for key")
469480
}
@@ -490,6 +501,7 @@ impl<'a, K: Eq + Hash, V> Entry<'a, K, V> {
490501

491502
/// Ensures a value is in the entry by inserting the default if empty, and returns
492503
/// a mutable reference to the value in the entry.
504+
#[inline]
493505
pub fn or_insert(self, value: V) -> &'a mut V {
494506
self.or_insert_with(|| value)
495507
}
@@ -515,6 +527,7 @@ impl<'a, K: Eq + Hash, V> Entry<'a, K, V> {
515527
}
516528

517529
/// Returns a reference to this entry's key.
530+
#[inline]
518531
pub fn key(&self) -> &K {
519532
&self.key
520533
}
@@ -523,6 +536,7 @@ impl<'a, K: Eq + Hash, V> Entry<'a, K, V> {
523536
impl<'a, K: Eq + Hash, V: Default> Entry<'a, K, V> {
524537
/// Ensures a value is in the entry by inserting the default value if empty,
525538
/// and returns a mutable reference to the value in the entry.
539+
#[inline]
526540
pub fn or_default(self) -> &'a mut V {
527541
self.or_insert_with(Default::default)
528542
}

compiler/rustc_data_structures/src/sso/mod.rs

+1-72
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,4 @@
1-
use std::fmt;
2-
use std::iter::ExactSizeIterator;
3-
use std::iter::FusedIterator;
4-
use std::iter::Iterator;
5-
6-
/// Iterator which may contain instance of
7-
/// one of two specific implementations.
8-
///
9-
/// Used by both SsoHashMap and SsoHashSet.
10-
#[derive(Clone)]
11-
pub enum EitherIter<L, R> {
12-
Left(L),
13-
Right(R),
14-
}
15-
16-
impl<L, R> Iterator for EitherIter<L, R>
17-
where
18-
L: Iterator,
19-
R: Iterator<Item = L::Item>,
20-
{
21-
type Item = L::Item;
22-
23-
fn next(&mut self) -> Option<Self::Item> {
24-
match self {
25-
EitherIter::Left(l) => l.next(),
26-
EitherIter::Right(r) => r.next(),
27-
}
28-
}
29-
30-
fn size_hint(&self) -> (usize, Option<usize>) {
31-
match self {
32-
EitherIter::Left(l) => l.size_hint(),
33-
EitherIter::Right(r) => r.size_hint(),
34-
}
35-
}
36-
}
37-
38-
impl<L, R> ExactSizeIterator for EitherIter<L, R>
39-
where
40-
L: ExactSizeIterator,
41-
R: ExactSizeIterator,
42-
EitherIter<L, R>: Iterator,
43-
{
44-
fn len(&self) -> usize {
45-
match self {
46-
EitherIter::Left(l) => l.len(),
47-
EitherIter::Right(r) => r.len(),
48-
}
49-
}
50-
}
51-
52-
impl<L, R> FusedIterator for EitherIter<L, R>
53-
where
54-
L: FusedIterator,
55-
R: FusedIterator,
56-
EitherIter<L, R>: Iterator,
57-
{
58-
}
59-
60-
impl<L, R> fmt::Debug for EitherIter<L, R>
61-
where
62-
L: fmt::Debug,
63-
R: fmt::Debug,
64-
{
65-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66-
match self {
67-
EitherIter::Left(l) => l.fmt(f),
68-
EitherIter::Right(r) => r.fmt(f),
69-
}
70-
}
71-
}
72-
1+
mod either_iter;
732
mod map;
743
mod set;
754

0 commit comments

Comments
 (0)