diff options
| author | Yuki Okushi <yuki.okushi@huawei.com> | 2021-06-18 18:22:41 +0900 |
|---|---|---|
| committer | Yuki Okushi <yuki.okushi@huawei.com> | 2021-07-23 18:04:21 +0900 |
| commit | cb3b3cf6abcd29f408b28cf3d59489a22ccc8897 (patch) | |
| tree | 6bdd753c6e6d593b20f5f810be9c8fd1ef6ed039 /compiler/rustc_data_structures/src | |
| parent | b2b7c859c1aae39d26884e760201f5e6c7feeff9 (diff) | |
| download | rust-cb3b3cf6abcd29f408b28cf3d59489a22ccc8897.tar.gz rust-cb3b3cf6abcd29f408b28cf3d59489a22ccc8897.zip | |
Improve `get_by_key_enumerated` more
Diffstat (limited to 'compiler/rustc_data_structures/src')
| -rw-r--r-- | compiler/rustc_data_structures/src/sorted_map/index_map.rs | 42 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sorted_map/tests.rs | 6 |
2 files changed, 10 insertions, 38 deletions
diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index 65689ab769c..2054f5eebf5 100644 --- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs @@ -1,6 +1,5 @@ //! A variant of `SortedMap` that preserves insertion order. -use std::borrow::Borrow; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; @@ -76,11 +75,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> { /// /// If there are multiple items that are equivalent to `key`, they will be yielded in /// insertion order. - pub fn get_by_key<Q: 'a>(&'a self, key: &Q) -> impl 'a + Iterator<Item = &'a V> - where - Q: Ord + ?Sized, - K: Borrow<Q>, - { + pub fn get_by_key(&'a self, key: K) -> impl 'a + Iterator<Item = &'a V> { self.get_by_key_enumerated(key).map(|(_, v)| v) } @@ -89,35 +84,12 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> { /// /// If there are multiple items that are equivalent to `key`, they will be yielded in /// insertion order. - pub fn get_by_key_enumerated<Q>(&self, key: &Q) -> impl '_ + Iterator<Item = (I, &V)> - where - Q: Ord + ?Sized, - K: Borrow<Q>, - { - match self.binary_search_idx(key) { - Err(_) => self.idxs_to_items_enumerated(&[]), - - Ok(idx) => { - let start = self.idx_sorted_by_item_key[..idx] - .partition_point(|&i| self.items[i].0.borrow() != key); - let end = idx - + self.idx_sorted_by_item_key[idx..] - .partition_point(|&i| self.items[i].0.borrow() == key); - self.idxs_to_items_enumerated(&self.idx_sorted_by_item_key[start..end]) - } - } - } - - fn binary_search_idx<Q>(&self, key: &Q) -> Result<usize, usize> - where - Q: Ord + ?Sized, - K: Borrow<Q>, - { - self.idx_sorted_by_item_key.binary_search_by(|&idx| self.items[idx].0.borrow().cmp(key)) - } - - fn idxs_to_items_enumerated(&'a self, idxs: &'a [I]) -> impl 'a + Iterator<Item = (I, &'a V)> { - idxs.iter().map(move |&idx| (idx, &self.items[idx].1)) + pub fn get_by_key_enumerated(&'a self, key: K) -> impl '_ + Iterator<Item = (I, &V)> { + let lower_bound = self.idx_sorted_by_item_key.partition_point(|&i| self.items[i].0 < key); + self.idx_sorted_by_item_key[lower_bound..] + .iter() + .take_while(move |&&i| self.items[i].0.eq(&key)) + .map(move |&idx| (idx, &self.items[idx].1)) } } diff --git a/compiler/rustc_data_structures/src/sorted_map/tests.rs b/compiler/rustc_data_structures/src/sorted_map/tests.rs index 7d91e1fdcef..1e977d709f1 100644 --- a/compiler/rustc_data_structures/src/sorted_map/tests.rs +++ b/compiler/rustc_data_structures/src/sorted_map/tests.rs @@ -14,11 +14,11 @@ fn test_sorted_index_multi_map() { } // `get_by_key` works. - assert_eq!(set.get_by_key(&3).copied().collect::<Vec<_>>(), vec![0]); - assert!(set.get_by_key(&4).next().is_none()); + assert_eq!(set.get_by_key(3).copied().collect::<Vec<_>>(), vec![0]); + assert!(set.get_by_key(4).next().is_none()); // `get_by_key` returns items in insertion order. - let twos: Vec<_> = set.get_by_key_enumerated(&2).collect(); + let twos: Vec<_> = set.get_by_key_enumerated(2).collect(); let idxs: Vec<usize> = twos.iter().map(|(i, _)| *i).collect(); let values: Vec<usize> = twos.iter().map(|(_, &v)| v).collect(); |
