Skip to content

Commit 9d7e63a

Browse files
committed
Use table entries (requires rust-lang#669)
1 parent 4d3c50f commit 9d7e63a

File tree

1 file changed

+59
-95
lines changed

1 file changed

+59
-95
lines changed

src/map.rs

Lines changed: 59 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,18 +1215,17 @@ where
12151215
#[cfg_attr(feature = "inline-more", inline)]
12161216
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A> {
12171217
let hash = make_hash::<K, S>(&self.hash_builder, &key);
1218-
if let Some(elem) = self.table.raw.find(hash, equivalent_key(&key)) {
1219-
Entry::Occupied(OccupiedEntry {
1220-
hash,
1221-
elem,
1222-
table: self,
1223-
})
1224-
} else {
1225-
Entry::Vacant(VacantEntry {
1226-
hash,
1218+
let hasher = make_hasher(&self.hash_builder);
1219+
match self.table.entry(hash, equivalent_key(&key), hasher) {
1220+
hash_table::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry {
1221+
inner,
1222+
marker: PhantomData,
1223+
}),
1224+
hash_table::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {
1225+
inner,
12271226
key,
1228-
table: self,
1229-
})
1227+
marker: PhantomData,
1228+
}),
12301229
}
12311230
}
12321231

@@ -1253,18 +1252,17 @@ where
12531252
Q: Hash + Equivalent<K> + ?Sized,
12541253
{
12551254
let hash = make_hash::<Q, S>(&self.hash_builder, key);
1256-
if let Some(elem) = self.table.raw.find(hash, equivalent_key(key)) {
1257-
EntryRef::Occupied(OccupiedEntry {
1258-
hash,
1259-
elem,
1260-
table: self,
1261-
})
1262-
} else {
1263-
EntryRef::Vacant(VacantEntryRef {
1264-
hash,
1255+
let hasher = make_hasher(&self.hash_builder);
1256+
match self.table.entry(hash, equivalent_key(key), hasher) {
1257+
hash_table::Entry::Occupied(inner) => EntryRef::Occupied(OccupiedEntry {
1258+
inner,
1259+
marker: PhantomData,
1260+
}),
1261+
hash_table::Entry::Vacant(inner) => EntryRef::Vacant(VacantEntryRef {
1262+
inner,
12651263
key,
1266-
table: self,
1267-
})
1264+
marker: PhantomData,
1265+
}),
12681266
}
12691267
}
12701268

@@ -2812,9 +2810,8 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for Entry<'_, K, V, S, A> {
28122810
/// assert_eq!(map.len(), 2);
28132811
/// ```
28142812
pub struct OccupiedEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
2815-
hash: u64,
2816-
elem: Bucket<(K, V)>,
2817-
table: &'a mut HashMap<K, V, S, A>,
2813+
inner: hash_table::OccupiedEntry<'a, (K, V), A>,
2814+
marker: PhantomData<&'a mut S>,
28182815
}
28192816

28202817
unsafe impl<K, V, S, A> Send for OccupiedEntry<'_, K, V, S, A>
@@ -2874,9 +2871,9 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedEntry<'_, K, V, S, A
28742871
/// assert!(map[&"b"] == 20 && map.len() == 2);
28752872
/// ```
28762873
pub struct VacantEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
2877-
hash: u64,
2874+
inner: hash_table::VacantEntry<'a, (K, V), A>,
28782875
key: K,
2879-
table: &'a mut HashMap<K, V, S, A>,
2876+
marker: PhantomData<&'a mut S>,
28802877
}
28812878

28822879
impl<K: Debug, V, S, A: Allocator> Debug for VacantEntry<'_, K, V, S, A> {
@@ -3018,9 +3015,9 @@ where
30183015
/// assert!(map["b"] == 20 && map.len() == 2);
30193016
/// ```
30203017
pub struct VacantEntryRef<'map, 'key, K, Q: ?Sized, V, S, A: Allocator = Global> {
3021-
hash: u64,
3018+
inner: hash_table::VacantEntry<'map, (K, V), A>,
30223019
key: &'key Q,
3023-
table: &'map mut HashMap<K, V, S, A>,
3020+
marker: PhantomData<&'map mut S>,
30243021
}
30253022

30263023
impl<K, Q, V, S, A> Debug for VacantEntryRef<'_, '_, K, Q, V, S, A>
@@ -3817,7 +3814,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38173814
/// ```
38183815
#[cfg_attr(feature = "inline-more", inline)]
38193816
pub fn key(&self) -> &K {
3820-
unsafe { &self.elem.as_ref().0 }
3817+
&self.inner.get().0
38213818
}
38223819

38233820
/// Take the ownership of the key and value from the map.
@@ -3846,7 +3843,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38463843
/// ```
38473844
#[cfg_attr(feature = "inline-more", inline)]
38483845
pub fn remove_entry(self) -> (K, V) {
3849-
unsafe { self.table.table.raw.remove(self.elem).0 }
3846+
self.inner.remove().0
38503847
}
38513848

38523849
/// Gets a reference to the value in the entry.
@@ -3867,7 +3864,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38673864
/// ```
38683865
#[cfg_attr(feature = "inline-more", inline)]
38693866
pub fn get(&self) -> &V {
3870-
unsafe { &self.elem.as_ref().1 }
3867+
&self.inner.get().1
38713868
}
38723869

38733870
/// Gets a mutable reference to the value in the entry.
@@ -3899,7 +3896,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38993896
/// ```
39003897
#[cfg_attr(feature = "inline-more", inline)]
39013898
pub fn get_mut(&mut self) -> &mut V {
3902-
unsafe { &mut self.elem.as_mut().1 }
3899+
&mut self.inner.get_mut().1
39033900
}
39043901

39053902
/// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
@@ -3930,7 +3927,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
39303927
/// ```
39313928
#[cfg_attr(feature = "inline-more", inline)]
39323929
pub fn into_mut(self) -> &'a mut V {
3933-
unsafe { &mut self.elem.as_mut().1 }
3930+
&mut self.inner.into_mut().1
39343931
}
39353932

39363933
/// Sets the value of the entry, and returns the entry's old value.
@@ -4036,30 +4033,27 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
40364033
where
40374034
F: FnOnce(&K, V) -> Option<V>,
40384035
{
4039-
unsafe {
4040-
let mut spare_key = None;
4041-
4042-
self.table
4043-
.table
4044-
.raw
4045-
.replace_bucket_with(self.elem.clone(), |(key, value)| {
4046-
if let Some(new_value) = f(&key, value) {
4047-
Some((key, new_value))
4048-
} else {
4049-
spare_key = Some(key);
4050-
None
4051-
}
4052-
});
4053-
4054-
if let Some(key) = spare_key {
4055-
Entry::Vacant(VacantEntry {
4056-
hash: self.hash,
4057-
key,
4058-
table: self.table,
4059-
})
4060-
} else {
4061-
Entry::Occupied(self)
4062-
}
4036+
let mut spare_key = None;
4037+
4038+
match unsafe {
4039+
self.inner.replace_entry_with(|(key, value)| {
4040+
if let Some(new_value) = f(&key, value) {
4041+
Some((key, new_value))
4042+
} else {
4043+
spare_key = Some(key);
4044+
None
4045+
}
4046+
})
4047+
} {
4048+
hash_table::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {
4049+
inner,
4050+
key: unsafe { spare_key.unwrap_unchecked() },
4051+
marker: PhantomData,
4052+
}),
4053+
hash_table::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry {
4054+
inner,
4055+
marker: PhantomData,
4056+
}),
40634057
}
40644058
}
40654059
}
@@ -4122,13 +4116,7 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41224116
K: Hash,
41234117
S: BuildHasher,
41244118
{
4125-
let table = &mut self.table.table.raw;
4126-
let entry = table.insert_entry(
4127-
self.hash,
4128-
(self.key, value),
4129-
make_hasher::<_, V, S>(&self.table.hash_builder),
4130-
);
4131-
&mut entry.1
4119+
&mut self.inner.insert((self.key, value)).into_mut().1
41324120
}
41334121

41344122
/// Sets the value of the entry with the [`VacantEntry`]'s key,
@@ -4153,15 +4141,9 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41534141
K: Hash,
41544142
S: BuildHasher,
41554143
{
4156-
let elem = self.table.table.raw.insert(
4157-
self.hash,
4158-
(self.key, value),
4159-
make_hasher::<_, V, S>(&self.table.hash_builder),
4160-
);
41614144
OccupiedEntry {
4162-
hash: self.hash,
4163-
elem,
4164-
table: self.table,
4145+
inner: self.inner.insert((self.key, value)),
4146+
marker: PhantomData,
41654147
}
41664148
}
41674149
}
@@ -4461,13 +4443,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
44614443
&'key Q: Into<K>,
44624444
S: BuildHasher,
44634445
{
4464-
let table = &mut self.table.table.raw;
4465-
let entry = table.insert_entry(
4466-
self.hash,
4467-
(self.key.into(), value),
4468-
make_hasher::<_, V, S>(&self.table.hash_builder),
4469-
);
4470-
&mut entry.1
4446+
&mut self.inner.insert((self.key.into(), value)).into_mut().1
44714447
}
44724448

44734449
/// Sets the key and value of the entry and returns a mutable reference to
@@ -4506,17 +4482,11 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45064482
Q: Equivalent<K>,
45074483
S: BuildHasher,
45084484
{
4509-
let table = &mut self.table.table.raw;
45104485
assert!(
45114486
(self.key).equivalent(&key),
45124487
"key used for Entry creation is not equivalent to the one used for insertion"
45134488
);
4514-
let entry = table.insert_entry(
4515-
self.hash,
4516-
(key, value),
4517-
make_hasher::<_, V, S>(&self.table.hash_builder),
4518-
);
4519-
&mut entry.1
4489+
&mut self.inner.insert((key, value)).into_mut().1
45204490
}
45214491

45224492
/// Sets the value of the entry with the [`VacantEntryRef`]'s key,
@@ -4542,15 +4512,9 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45424512
&'key Q: Into<K>,
45434513
S: BuildHasher,
45444514
{
4545-
let elem = self.table.table.raw.insert(
4546-
self.hash,
4547-
(self.key.into(), value),
4548-
make_hasher::<_, V, S>(&self.table.hash_builder),
4549-
);
45504515
OccupiedEntry {
4551-
hash: self.hash,
4552-
elem,
4553-
table: self.table,
4516+
inner: self.inner.insert((self.key.into(), value)),
4517+
marker: PhantomData,
45544518
}
45554519
}
45564520
}

0 commit comments

Comments
 (0)