Skip to content

Commit a7bb479

Browse files
committed
rollup merge of #19935: cgaebel/hashmap-tuple-indexing
r? @gankro @pczarn
2 parents 42dbee0 + c42e2f6 commit a7bb479

File tree

3 files changed

+41
-88
lines changed

3 files changed

+41
-88
lines changed

src/libstd/collections/hash/map.rs

Lines changed: 38 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ pub struct HashMap<K, V, H = RandomSipHasher> {
297297

298298
/// Search for a pre-hashed key.
299299
fn search_hashed<K, V, M, F>(table: M,
300-
hash: &SafeHash,
300+
hash: SafeHash,
301301
mut is_match: F)
302302
-> SearchResult<K, V, M> where
303303
M: Deref<RawTable<K, V>>,
@@ -320,14 +320,9 @@ fn search_hashed<K, V, M, F>(table: M,
320320
}
321321

322322
// If the hash doesn't match, it can't be this one..
323-
if *hash == full.hash() {
324-
let matched = {
325-
let (k, _) = full.read();
326-
is_match(k)
327-
};
328-
323+
if hash == full.hash() {
329324
// If the key doesn't match, it can't be this one..
330-
if matched {
325+
if is_match(full.read().0) {
331326
return FoundExisting(full);
332327
}
333328
}
@@ -353,7 +348,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
353348
}
354349

355350
// Now we've done all our shifting. Return the value we grabbed earlier.
356-
return (retkey, retval);
351+
(retkey, retval)
357352
}
358353

359354
/// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -389,10 +384,11 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
389384
let b = bucket.put(old_hash, old_key, old_val);
390385
// Now that it's stolen, just read the value's pointer
391386
// right out of the table!
392-
let (_, v) = Bucket::at_index(b.into_table(), starting_index).peek()
393-
.expect_full()
394-
.into_mut_refs();
395-
return v;
387+
return Bucket::at_index(b.into_table(), starting_index)
388+
.peek()
389+
.expect_full()
390+
.into_mut_refs()
391+
.1;
396392
},
397393
table::Full(bucket) => bucket
398394
};
@@ -441,14 +437,14 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
441437
fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
442438
-> Option<FullBucketImm<'a, K, V>> {
443439
let hash = self.make_hash(q);
444-
search_hashed(&self.table, &hash, |k| q.equiv(k)).into_option()
440+
search_hashed(&self.table, hash, |k| q.equiv(k)).into_option()
445441
}
446442

447443
#[allow(deprecated)]
448444
fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
449445
-> Option<FullBucketMut<'a, K, V>> {
450446
let hash = self.make_hash(q);
451-
search_hashed(&mut self.table, &hash, |k| q.equiv(k)).into_option()
447+
search_hashed(&mut self.table, hash, |k| q.equiv(k)).into_option()
452448
}
453449

454450
/// Search for a key, yielding the index if it's found in the hashtable.
@@ -458,22 +454,22 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
458454
where Q: BorrowFrom<K> + Eq + Hash<S>
459455
{
460456
let hash = self.make_hash(q);
461-
search_hashed(&self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k)))
457+
search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
462458
.into_option()
463459
}
464460

465461
fn search_mut<'a, Sized? Q>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
466462
where Q: BorrowFrom<K> + Eq + Hash<S>
467463
{
468464
let hash = self.make_hash(q);
469-
search_hashed(&mut self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k)))
465+
search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
470466
.into_option()
471467
}
472468

473469
// The caller should ensure that invariants by Robin Hood Hashing hold.
474470
fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
475471
let cap = self.table.capacity();
476-
let mut buckets = Bucket::new(&mut self.table, &hash);
472+
let mut buckets = Bucket::new(&mut self.table, hash);
477473
let ib = buckets.index();
478474

479475
while buckets.index() != ib + cap {
@@ -762,26 +758,22 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
762758
{
763759
// Worst case, we'll find one empty bucket among `size + 1` buckets.
764760
let size = self.table.size();
765-
let mut probe = Bucket::new(&mut self.table, &hash);
761+
let mut probe = Bucket::new(&mut self.table, hash);
766762
let ib = probe.index();
767763

768764
loop {
769765
let mut bucket = match probe.peek() {
770766
Empty(bucket) => {
771767
// Found a hole!
772-
let bucket = bucket.put(hash, k, v);
773-
let (_, val) = bucket.into_mut_refs();
774-
return val;
775-
},
768+
return bucket.put(hash, k, v).into_mut_refs().1;
769+
}
776770
Full(bucket) => bucket
777771
};
778772

773+
// hash matches?
779774
if bucket.hash() == hash {
780-
let found_match = {
781-
let (bucket_k, _) = bucket.read_mut();
782-
k == *bucket_k
783-
};
784-
if found_match {
775+
// key matches?
776+
if k == *bucket.read_mut().0 {
785777
let (bucket_k, bucket_v) = bucket.into_mut_refs();
786778
debug_assert!(k == *bucket_k);
787779
// Key already exists. Get its reference.
@@ -811,13 +803,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
811803
/// Deprecated: use `get` and `BorrowFrom` instead.
812804
#[deprecated = "use get and BorrowFrom instead"]
813805
pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
814-
match self.search_equiv(k) {
815-
None => None,
816-
Some(bucket) => {
817-
let (_, v_ref) = bucket.into_refs();
818-
Some(v_ref)
819-
}
820-
}
806+
self.search_equiv(k).map(|bucket| bucket.into_refs().1)
821807
}
822808

823809
/// Deprecated: use `remove` and `BorrowFrom` instead.
@@ -829,13 +815,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
829815

830816
self.reserve(1);
831817

832-
match self.search_equiv_mut(k) {
833-
Some(bucket) => {
834-
let (_k, val) = pop_internal(bucket);
835-
Some(val)
836-
}
837-
_ => None
838-
}
818+
self.search_equiv_mut(k).map(|bucket| pop_internal(bucket).1)
839819
}
840820

841821
/// An iterator visiting all keys in arbitrary order.
@@ -1022,11 +1002,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
10221002

10231003
while buckets.index() != cap {
10241004
buckets = match buckets.peek() {
1025-
Empty(b) => b.next(),
1026-
Full(full) => {
1027-
let (b, _, _) = full.take();
1028-
b.next()
1029-
}
1005+
Empty(b) => b.next(),
1006+
Full(full) => full.take().0.next(),
10301007
};
10311008
}
10321009
}
@@ -1057,10 +1034,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
10571034
pub fn get<Sized? Q>(&self, k: &Q) -> Option<&V>
10581035
where Q: Hash<S> + Eq + BorrowFrom<K>
10591036
{
1060-
self.search(k).map(|bucket| {
1061-
let (_, v) = bucket.into_refs();
1062-
v
1063-
})
1037+
self.search(k).map(|bucket| bucket.into_refs().1)
10641038
}
10651039

10661040
/// Returns true if the map contains a value for the specified key.
@@ -1115,13 +1089,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
11151089
pub fn get_mut<Sized? Q>(&mut self, k: &Q) -> Option<&mut V>
11161090
where Q: Hash<S> + Eq + BorrowFrom<K>
11171091
{
1118-
match self.search_mut(k) {
1119-
Some(bucket) => {
1120-
let (_, v) = bucket.into_mut_refs();
1121-
Some(v)
1122-
}
1123-
_ => None
1124-
}
1092+
self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
11251093
}
11261094

11271095
/// Deprecated: Renamed to `insert`.
@@ -1189,18 +1157,15 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
11891157
return None
11901158
}
11911159

1192-
self.search_mut(k).map(|bucket| {
1193-
let (_k, val) = pop_internal(bucket);
1194-
val
1195-
})
1160+
self.search_mut(k).map(|bucket| pop_internal(bucket).1)
11961161
}
11971162
}
11981163

11991164
fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
12001165
-> Entry<'a, K, V> {
12011166
// Worst case, we'll find one empty bucket among `size + 1` buckets.
12021167
let size = table.size();
1203-
let mut probe = Bucket::new(table, &hash);
1168+
let mut probe = Bucket::new(table, hash);
12041169
let ib = probe.index();
12051170

12061171
loop {
@@ -1216,13 +1181,10 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas
12161181
Full(bucket) => bucket
12171182
};
12181183

1184+
// hash matches?
12191185
if bucket.hash() == hash {
1220-
let is_eq = {
1221-
let (bucket_k, _) = bucket.read();
1222-
k == *bucket_k
1223-
};
1224-
1225-
if is_eq {
1186+
// key matches?
1187+
if k == *bucket.read().0 {
12261188
return Occupied(OccupiedEntry{
12271189
elem: bucket,
12281190
});
@@ -1310,10 +1272,7 @@ impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> IndexMut<Q, V> for HashMap<K
13101272
{
13111273
#[inline]
13121274
fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
1313-
match self.get_mut(index) {
1314-
Some(v) => v,
1315-
None => panic!("no entry found for key")
1316-
}
1275+
self.get_mut(index).expect("no entry found for key")
13171276
}
13181277
}
13191278

@@ -1404,21 +1363,18 @@ impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> {
14041363
impl<'a, K, V> OccupiedEntry<'a, K, V> {
14051364
/// Gets a reference to the value in the entry
14061365
pub fn get(&self) -> &V {
1407-
let (_, v) = self.elem.read();
1408-
v
1366+
self.elem.read().1
14091367
}
14101368

14111369
/// Gets a mutable reference to the value in the entry
14121370
pub fn get_mut(&mut self) -> &mut V {
1413-
let (_, v) = self.elem.read_mut();
1414-
v
1371+
self.elem.read_mut().1
14151372
}
14161373

14171374
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
14181375
/// with a lifetime bound to the map itself
14191376
pub fn into_mut(self) -> &'a mut V {
1420-
let (_, v) = self.elem.into_mut_refs();
1421-
v
1377+
self.elem.into_mut_refs().1
14221378
}
14231379

14241380
/// Sets the value of the entry, and returns the entry's old value
@@ -1430,8 +1386,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
14301386

14311387
/// Takes the value out of the entry, and returns it
14321388
pub fn take(self) -> V {
1433-
let (_, v) = pop_internal(self.elem);
1434-
v
1389+
pop_internal(self.elem).1
14351390
}
14361391
}
14371392

@@ -1444,17 +1399,15 @@ impl<'a, K, V> VacantEntry<'a, K, V> {
14441399
robin_hood(bucket, ib, self.hash, self.key, value)
14451400
}
14461401
NoElem(bucket) => {
1447-
let full = bucket.put(self.hash, self.key, value);
1448-
let (_, v) = full.into_mut_refs();
1449-
v
1402+
bucket.put(self.hash, self.key, value).into_mut_refs().1
14501403
}
14511404
}
14521405
}
14531406
}
14541407

14551408
impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
14561409
fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
1457-
let (lower, _) = iter.size_hint();
1410+
let lower = iter.size_hint().0;
14581411
let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
14591412
map.extend(iter);
14601413
map

src/libstd/collections/hash/set.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
593593

594594
impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
595595
fn from_iter<I: Iterator<T>>(iter: I) -> HashSet<T, H> {
596-
let (lower, _) = iter.size_hint();
596+
let lower = iter.size_hint().0;
597597
let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
598598
set.extend(iter);
599599
set

src/libstd/collections/hash/table.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ struct GapThenFull<K, V, M> {
124124

125125
/// A hash that is not zero, since we use a hash of zero to represent empty
126126
/// buckets.
127-
#[deriving(PartialEq)]
127+
#[deriving(PartialEq, Copy)]
128128
pub struct SafeHash {
129129
hash: u64,
130130
}
@@ -211,7 +211,7 @@ impl<K, V, M> Bucket<K, V, M> {
211211
}
212212

213213
impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> {
214-
pub fn new(table: M, hash: &SafeHash) -> Bucket<K, V, M> {
214+
pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
215215
Bucket::at_index(table, hash.inspect() as uint)
216216
}
217217

0 commit comments

Comments
 (0)