Skip to content

Commit 50b9e38

Browse files
committed
Use table entries (requires rust-lang#669)
1 parent c19e205 commit 50b9e38

File tree

1 file changed

+61
-102
lines changed

1 file changed

+61
-102
lines changed

src/map.rs

Lines changed: 61 additions & 102 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

@@ -1827,12 +1825,10 @@ where
18271825
#[cfg_attr(feature = "inline-more", inline)]
18281826
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
18291827
let hash = make_hash::<K, S>(&self.hash_builder, &k);
1830-
match self.find_or_find_insert_index(hash, &k) {
1831-
Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)),
1832-
Err(index) => {
1833-
unsafe {
1834-
self.table.raw.insert_at_index(hash, index, (k, v));
1835-
}
1828+
match self.entry(k) {
1829+
Entry::Occupied(mut entry) => Some(entry.insert(v)),
1830+
Entry::Vacant(entry) => {
1831+
entry.insert(v);
18361832
None
18371833
}
18381834
}
@@ -1914,11 +1910,10 @@ where
19141910
#[cfg_attr(feature = "inline-more", inline)]
19151911
pub unsafe fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
19161912
let hash = make_hash::<K, S>(&self.hash_builder, &k);
1917-
let bucket =
1913+
let entry =
19181914
self.table
1919-
.raw
1920-
.insert(hash, (k, v), make_hasher::<_, V, S>(&self.hash_builder));
1921-
let (k_ref, v_ref) = unsafe { bucket.as_mut() };
1915+
.insert_unique(hash, (k, v), make_hasher::<_, V, S>(&self.hash_builder));
1916+
let (k_ref, v_ref) = entry.into_mut();
19221917
(k_ref, v_ref)
19231918
}
19241919

@@ -2812,9 +2807,8 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for Entry<'_, K, V, S, A> {
28122807
/// assert_eq!(map.len(), 2);
28132808
/// ```
28142809
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>,
2810+
inner: hash_table::OccupiedEntry<'a, (K, V), A>,
2811+
marker: PhantomData<&'a mut S>,
28182812
}
28192813

28202814
unsafe impl<K, V, S, A> Send for OccupiedEntry<'_, K, V, S, A>
@@ -2874,9 +2868,9 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedEntry<'_, K, V, S, A
28742868
/// assert!(map[&"b"] == 20 && map.len() == 2);
28752869
/// ```
28762870
pub struct VacantEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
2877-
hash: u64,
2871+
inner: hash_table::VacantEntry<'a, (K, V), A>,
28782872
key: K,
2879-
table: &'a mut HashMap<K, V, S, A>,
2873+
marker: PhantomData<&'a mut S>,
28802874
}
28812875

28822876
impl<K: Debug, V, S, A: Allocator> Debug for VacantEntry<'_, K, V, S, A> {
@@ -3018,9 +3012,9 @@ where
30183012
/// assert!(map["b"] == 20 && map.len() == 2);
30193013
/// ```
30203014
pub struct VacantEntryRef<'map, 'key, K, Q: ?Sized, V, S, A: Allocator = Global> {
3021-
hash: u64,
3015+
inner: hash_table::VacantEntry<'map, (K, V), A>,
30223016
key: &'key Q,
3023-
table: &'map mut HashMap<K, V, S, A>,
3017+
marker: PhantomData<&'map mut S>,
30243018
}
30253019

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

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

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

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

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

39363930
/// Sets the value of the entry, and returns the entry's old value.
@@ -4036,30 +4030,25 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
40364030
where
40374031
F: FnOnce(&K, V) -> Option<V>,
40384032
{
4039-
unsafe {
4040-
let mut spare_key = None;
4033+
let mut spare_key = None;
40414034

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-
})
4035+
match self.inner.replace_entry_with(|(key, value)| {
4036+
if let Some(new_value) = f(&key, value) {
4037+
Some((key, new_value))
40604038
} else {
4061-
Entry::Occupied(self)
4039+
spare_key = Some(key);
4040+
None
40624041
}
4042+
}) {
4043+
hash_table::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {
4044+
inner,
4045+
key: unsafe { spare_key.unwrap_unchecked() },
4046+
marker: PhantomData,
4047+
}),
4048+
hash_table::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry {
4049+
inner,
4050+
marker: PhantomData,
4051+
}),
40634052
}
40644053
}
40654054
}
@@ -4122,13 +4111,7 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41224111
K: Hash,
41234112
S: BuildHasher,
41244113
{
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
4114+
&mut self.inner.insert((self.key, value)).into_mut().1
41324115
}
41334116

41344117
/// Sets the value of the entry with the [`VacantEntry`]'s key,
@@ -4153,15 +4136,9 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41534136
K: Hash,
41544137
S: BuildHasher,
41554138
{
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-
);
41614139
OccupiedEntry {
4162-
hash: self.hash,
4163-
elem,
4164-
table: self.table,
4140+
inner: self.inner.insert((self.key, value)),
4141+
marker: PhantomData,
41654142
}
41664143
}
41674144
}
@@ -4461,13 +4438,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
44614438
&'key Q: Into<K>,
44624439
S: BuildHasher,
44634440
{
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
4441+
&mut self.inner.insert((self.key.into(), value)).into_mut().1
44714442
}
44724443

44734444
/// Sets the key and value of the entry and returns a mutable reference to
@@ -4506,17 +4477,11 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45064477
Q: Equivalent<K>,
45074478
S: BuildHasher,
45084479
{
4509-
let table = &mut self.table.table.raw;
45104480
assert!(
45114481
(self.key).equivalent(&key),
45124482
"key used for Entry creation is not equivalent to the one used for insertion"
45134483
);
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
4484+
&mut self.inner.insert((key, value)).into_mut().1
45204485
}
45214486

45224487
/// Sets the value of the entry with the [`VacantEntryRef`]'s key,
@@ -4542,15 +4507,9 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45424507
&'key Q: Into<K>,
45434508
S: BuildHasher,
45444509
{
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-
);
45504510
OccupiedEntry {
4551-
hash: self.hash,
4552-
elem,
4553-
table: self.table,
4511+
inner: self.inner.insert((self.key.into(), value)),
4512+
marker: PhantomData,
45544513
}
45554514
}
45564515
}

0 commit comments

Comments
 (0)