Skip to content

Commit 43a847f

Browse files
committed
Use table entries (requires rust-lang#669)
1 parent 541dd95 commit 43a847f

File tree

1 file changed

+54
-92
lines changed

1 file changed

+54
-92
lines changed

src/map.rs

Lines changed: 54 additions & 92 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,25 @@ 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-
});
4036+
let mut spare_key = None;
40534037

4054-
if let Some(key) = spare_key {
4055-
Entry::Vacant(VacantEntry {
4056-
hash: self.hash,
4057-
key,
4058-
table: self.table,
4059-
})
4038+
match self.inner.replace_entry_with(|(key, value)| {
4039+
if let Some(new_value) = f(&key, value) {
4040+
Some((key, new_value))
40604041
} else {
4061-
Entry::Occupied(self)
4042+
spare_key = Some(key);
4043+
None
40624044
}
4045+
}) {
4046+
hash_table::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {
4047+
inner,
4048+
key: unsafe { spare_key.unwrap_unchecked() },
4049+
marker: PhantomData,
4050+
}),
4051+
hash_table::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry {
4052+
inner,
4053+
marker: PhantomData,
4054+
}),
40634055
}
40644056
}
40654057
}
@@ -4122,13 +4114,7 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41224114
K: Hash,
41234115
S: BuildHasher,
41244116
{
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
4117+
&mut self.inner.insert((self.key, value)).into_mut().1
41324118
}
41334119

41344120
/// Sets the value of the entry with the [`VacantEntry`]'s key,
@@ -4153,15 +4139,9 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41534139
K: Hash,
41544140
S: BuildHasher,
41554141
{
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-
);
41614142
OccupiedEntry {
4162-
hash: self.hash,
4163-
elem,
4164-
table: self.table,
4143+
inner: self.inner.insert((self.key, value)),
4144+
marker: PhantomData,
41654145
}
41664146
}
41674147
}
@@ -4461,13 +4441,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
44614441
&'key Q: Into<K>,
44624442
S: BuildHasher,
44634443
{
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
4444+
&mut self.inner.insert((self.key.into(), value)).into_mut().1
44714445
}
44724446

44734447
/// Sets the key and value of the entry and returns a mutable reference to
@@ -4506,17 +4480,11 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45064480
Q: Equivalent<K>,
45074481
S: BuildHasher,
45084482
{
4509-
let table = &mut self.table.table.raw;
45104483
assert!(
45114484
(self.key).equivalent(&key),
45124485
"key used for Entry creation is not equivalent to the one used for insertion"
45134486
);
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
4487+
&mut self.inner.insert((key, value)).into_mut().1
45204488
}
45214489

45224490
/// Sets the value of the entry with the [`VacantEntryRef`]'s key,
@@ -4542,15 +4510,9 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45424510
&'key Q: Into<K>,
45434511
S: BuildHasher,
45444512
{
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-
);
45504513
OccupiedEntry {
4551-
hash: self.hash,
4552-
elem,
4553-
table: self.table,
4514+
inner: self.inner.insert((self.key.into(), value)),
4515+
marker: PhantomData,
45544516
}
45554517
}
45564518
}

0 commit comments

Comments
 (0)