Skip to content

Commit 1e3588d

Browse files
committed
Use table entries
1 parent 107804f commit 1e3588d

File tree

3 files changed

+77
-126
lines changed

3 files changed

+77
-126
lines changed

src/map.rs

Lines changed: 63 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,18 +1183,17 @@ where
11831183
#[cfg_attr(feature = "inline-more", inline)]
11841184
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A> {
11851185
let hash = make_hash::<K, S>(&self.hash_builder, &key);
1186-
if let Some(elem) = self.table.raw.find(hash, equivalent_key(&key)) {
1187-
Entry::Occupied(OccupiedEntry {
1188-
hash,
1189-
elem,
1190-
table: self,
1191-
})
1192-
} else {
1193-
Entry::Vacant(VacantEntry {
1194-
hash,
1186+
let hasher = make_hasher(&self.hash_builder);
1187+
match self.table.entry(hash, equivalent_key(&key), hasher) {
1188+
table::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry {
1189+
inner,
1190+
marker: PhantomData,
1191+
}),
1192+
table::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {
1193+
inner,
11951194
key,
1196-
table: self,
1197-
})
1195+
marker: PhantomData,
1196+
}),
11981197
}
11991198
}
12001199

@@ -1221,18 +1220,17 @@ where
12211220
Q: Hash + Equivalent<K> + ?Sized,
12221221
{
12231222
let hash = make_hash::<Q, S>(&self.hash_builder, key);
1224-
if let Some(elem) = self.table.raw.find(hash, equivalent_key(key)) {
1225-
EntryRef::Occupied(OccupiedEntry {
1226-
hash,
1227-
elem,
1228-
table: self,
1229-
})
1230-
} else {
1231-
EntryRef::Vacant(VacantEntryRef {
1232-
hash,
1223+
let hasher = make_hasher(&self.hash_builder);
1224+
match self.table.entry(hash, equivalent_key(key), hasher) {
1225+
table::Entry::Occupied(inner) => EntryRef::Occupied(OccupiedEntry {
1226+
inner,
1227+
marker: PhantomData,
1228+
}),
1229+
table::Entry::Vacant(inner) => EntryRef::Vacant(VacantEntryRef {
1230+
inner,
12331231
key,
1234-
table: self,
1235-
})
1232+
marker: PhantomData,
1233+
}),
12361234
}
12371235
}
12381236

@@ -1781,13 +1779,10 @@ where
17811779
/// ```
17821780
#[cfg_attr(feature = "inline-more", inline)]
17831781
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
1784-
let hash = make_hash::<K, S>(&self.hash_builder, &k);
1785-
match self.find_or_find_insert_index(hash, &k) {
1786-
Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)),
1787-
Err(index) => {
1788-
unsafe {
1789-
self.table.raw.insert_at_index(hash, index, (k, v));
1790-
}
1782+
match self.entry(k) {
1783+
Entry::Occupied(mut entry) => Some(entry.insert(v)),
1784+
Entry::Vacant(entry) => {
1785+
entry.insert(v);
17911786
None
17921787
}
17931788
}
@@ -1869,11 +1864,10 @@ where
18691864
#[cfg_attr(feature = "inline-more", inline)]
18701865
pub unsafe fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
18711866
let hash = make_hash::<K, S>(&self.hash_builder, &k);
1872-
let bucket =
1867+
let entry =
18731868
self.table
1874-
.raw
1875-
.insert(hash, (k, v), make_hasher::<_, V, S>(&self.hash_builder));
1876-
let (k_ref, v_ref) = unsafe { bucket.as_mut() };
1869+
.insert_unique(hash, (k, v), make_hasher::<_, V, S>(&self.hash_builder));
1870+
let (k_ref, v_ref) = entry.into_mut();
18771871
(k_ref, v_ref)
18781872
}
18791873

@@ -2749,9 +2743,8 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for Entry<'_, K, V, S, A> {
27492743
/// assert_eq!(map.len(), 2);
27502744
/// ```
27512745
pub struct OccupiedEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
2752-
hash: u64,
2753-
elem: Bucket<(K, V)>,
2754-
table: &'a mut HashMap<K, V, S, A>,
2746+
inner: table::OccupiedEntry<'a, (K, V), A>,
2747+
marker: PhantomData<&'a mut S>,
27552748
}
27562749

27572750
unsafe impl<K, V, S, A> Send for OccupiedEntry<'_, K, V, S, A>
@@ -2809,9 +2802,9 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedEntry<'_, K, V, S, A
28092802
/// assert!(map[&"b"] == 20 && map.len() == 2);
28102803
/// ```
28112804
pub struct VacantEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
2812-
hash: u64,
2805+
inner: table::VacantEntry<'a, (K, V), A>,
28132806
key: K,
2814-
table: &'a mut HashMap<K, V, S, A>,
2807+
marker: PhantomData<&'a mut S>,
28152808
}
28162809

28172810
impl<K: Debug, V, S, A: Allocator> Debug for VacantEntry<'_, K, V, S, A> {
@@ -2947,9 +2940,9 @@ where
29472940
/// assert!(map["b"] == 20 && map.len() == 2);
29482941
/// ```
29492942
pub struct VacantEntryRef<'map, 'key, K, Q: ?Sized, V, S, A: Allocator = Global> {
2950-
hash: u64,
2943+
inner: table::VacantEntry<'map, (K, V), A>,
29512944
key: &'key Q,
2952-
table: &'map mut HashMap<K, V, S, A>,
2945+
marker: PhantomData<&'map mut S>,
29532946
}
29542947

29552948
impl<K, Q, V, S, A> Debug for VacantEntryRef<'_, '_, K, Q, V, S, A>
@@ -3754,7 +3747,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
37543747
/// ```
37553748
#[cfg_attr(feature = "inline-more", inline)]
37563749
pub fn key(&self) -> &K {
3757-
unsafe { &self.elem.as_ref().0 }
3750+
&self.inner.get().0
37583751
}
37593752

37603753
/// Take the ownership of the key and value from the map.
@@ -3783,7 +3776,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
37833776
/// ```
37843777
#[cfg_attr(feature = "inline-more", inline)]
37853778
pub fn remove_entry(self) -> (K, V) {
3786-
unsafe { self.table.table.raw.remove(self.elem).0 }
3779+
self.inner.remove().0
37873780
}
37883781

37893782
/// Gets a reference to the value in the entry.
@@ -3804,7 +3797,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38043797
/// ```
38053798
#[cfg_attr(feature = "inline-more", inline)]
38063799
pub fn get(&self) -> &V {
3807-
unsafe { &self.elem.as_ref().1 }
3800+
&self.inner.get().1
38083801
}
38093802

38103803
/// Gets a mutable reference to the value in the entry.
@@ -3836,7 +3829,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38363829
/// ```
38373830
#[cfg_attr(feature = "inline-more", inline)]
38383831
pub fn get_mut(&mut self) -> &mut V {
3839-
unsafe { &mut self.elem.as_mut().1 }
3832+
&mut self.inner.get_mut().1
38403833
}
38413834

38423835
/// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
@@ -3867,7 +3860,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38673860
/// ```
38683861
#[cfg_attr(feature = "inline-more", inline)]
38693862
pub fn into_mut(self) -> &'a mut V {
3870-
unsafe { &mut self.elem.as_mut().1 }
3863+
&mut self.inner.into_mut().1
38713864
}
38723865

38733866
/// Converts the `OccupiedEntry` into a reference to the key and a
@@ -3902,7 +3895,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
39023895
/// ```
39033896
#[cfg_attr(feature = "inline-more", inline)]
39043897
pub fn into_entry(self) -> (&'a K, &'a mut V) {
3905-
let (key, val) = unsafe { self.elem.as_mut() };
3898+
let (key, val) = self.inner.into_mut();
39063899
(key, val)
39073900
}
39083901

@@ -4009,30 +4002,25 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
40094002
where
40104003
F: FnOnce(&K, V) -> Option<V>,
40114004
{
4012-
unsafe {
4013-
let mut spare_key = None;
4005+
let mut spare_key = None;
40144006

4015-
self.table
4016-
.table
4017-
.raw
4018-
.replace_bucket_with(self.elem.clone(), |(key, value)| {
4019-
if let Some(new_value) = f(&key, value) {
4020-
Some((key, new_value))
4021-
} else {
4022-
spare_key = Some(key);
4023-
None
4024-
}
4025-
});
4026-
4027-
if let Some(key) = spare_key {
4028-
Entry::Vacant(VacantEntry {
4029-
hash: self.hash,
4030-
key,
4031-
table: self.table,
4032-
})
4007+
match self.inner.replace_entry_with(|(key, value)| {
4008+
if let Some(new_value) = f(&key, value) {
4009+
Some((key, new_value))
40334010
} else {
4034-
Entry::Occupied(self)
4011+
spare_key = Some(key);
4012+
None
40354013
}
4014+
}) {
4015+
table::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {
4016+
inner,
4017+
key: unsafe { spare_key.unwrap_unchecked() },
4018+
marker: PhantomData,
4019+
}),
4020+
table::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry {
4021+
inner,
4022+
marker: PhantomData,
4023+
}),
40364024
}
40374025
}
40384026
}
@@ -4095,13 +4083,7 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
40954083
K: Hash,
40964084
S: BuildHasher,
40974085
{
4098-
let table = &mut self.table.table.raw;
4099-
let entry = table.insert_entry(
4100-
self.hash,
4101-
(self.key, value),
4102-
make_hasher::<_, V, S>(&self.table.hash_builder),
4103-
);
4104-
&mut entry.1
4086+
&mut self.inner.insert((self.key, value)).into_mut().1
41054087
}
41064088

41074089
/// Sets the value of the entry with the [`VacantEntry`]'s key,
@@ -4126,15 +4108,9 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41264108
K: Hash,
41274109
S: BuildHasher,
41284110
{
4129-
let elem = self.table.table.raw.insert(
4130-
self.hash,
4131-
(self.key, value),
4132-
make_hasher::<_, V, S>(&self.table.hash_builder),
4133-
);
41344111
OccupiedEntry {
4135-
hash: self.hash,
4136-
elem,
4137-
table: self.table,
4112+
inner: self.inner.insert((self.key, value)),
4113+
marker: PhantomData,
41384114
}
41394115
}
41404116
}
@@ -4435,13 +4411,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
44354411
Q: ToOwned<Owned = K>,
44364412
S: BuildHasher,
44374413
{
4438-
let table = &mut self.table.table.raw;
4439-
let entry = table.insert_entry(
4440-
self.hash,
4441-
(self.key.to_owned(), value),
4442-
make_hasher::<_, V, S>(&self.table.hash_builder),
4443-
);
4444-
&mut entry.1
4414+
&mut self.inner.insert((self.key.to_owned(), value)).into_mut().1
44454415
}
44464416

44474417
/// Sets the key and value of the entry and returns a mutable reference to
@@ -4506,15 +4476,9 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45064476
Q: ToOwned<Owned = K>,
45074477
S: BuildHasher,
45084478
{
4509-
let elem = self.table.table.raw.insert(
4510-
self.hash,
4511-
(self.key.to_owned(), value),
4512-
make_hasher::<_, V, S>(&self.table.hash_builder),
4513-
);
45144479
OccupiedEntry {
4515-
hash: self.hash,
4516-
elem,
4517-
table: self.table,
4480+
inner: self.inner.insert((self.key.to_owned(), value)),
4481+
marker: PhantomData,
45184482
}
45194483
}
45204484

@@ -4557,15 +4521,9 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45574521
(self.key).equivalent(&key),
45584522
"key used for Entry creation is not equivalent to the one used for insertion"
45594523
);
4560-
let elem = self.table.table.raw.insert(
4561-
self.hash,
4562-
(key, value),
4563-
make_hasher::<_, V, S>(&self.table.hash_builder),
4564-
);
45654524
OccupiedEntry {
4566-
hash: self.hash,
4567-
elem,
4568-
table: self.table,
4525+
inner: self.inner.insert((key, value)),
4526+
marker: PhantomData,
45694527
}
45704528
}
45714529
}

src/raw/mod.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,19 +1060,6 @@ impl<T, A: Allocator> RawTable<T, A> {
10601060
}
10611061
}
10621062

1063-
/// Inserts a new element into the table, and returns a mutable reference to it.
1064-
///
1065-
/// This does not check if the given element already exists in the table.
1066-
#[cfg_attr(feature = "inline-more", inline)]
1067-
pub(crate) fn insert_entry(
1068-
&mut self,
1069-
hash: u64,
1070-
value: T,
1071-
hasher: impl Fn(&T) -> u64,
1072-
) -> &mut T {
1073-
unsafe { self.insert(hash, value, hasher).as_mut() }
1074-
}
1075-
10761063
/// Inserts a new element into the table, without growing the table.
10771064
///
10781065
/// There must be enough space in the table to insert the new element.

src/raw_entry.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,11 +1353,15 @@ impl<'a, K, V, S, A: Allocator> RawVacantEntryMut<'a, K, V, S, A> {
13531353
K: Hash,
13541354
S: BuildHasher,
13551355
{
1356-
let &mut (ref mut k, ref mut v) = self.table.insert_entry(
1357-
hash,
1358-
(key, value),
1359-
make_hasher::<_, V, S>(self.hash_builder),
1360-
);
1356+
let &mut (ref mut k, ref mut v) = unsafe {
1357+
self.table
1358+
.insert(
1359+
hash,
1360+
(key, value),
1361+
make_hasher::<_, V, S>(self.hash_builder),
1362+
)
1363+
.as_mut()
1364+
};
13611365
(k, v)
13621366
}
13631367

@@ -1408,9 +1412,11 @@ impl<'a, K, V, S, A: Allocator> RawVacantEntryMut<'a, K, V, S, A> {
14081412
where
14091413
H: Fn(&K) -> u64,
14101414
{
1411-
let &mut (ref mut k, ref mut v) = self
1412-
.table
1413-
.insert_entry(hash, (key, value), |x| hasher(&x.0));
1415+
let &mut (ref mut k, ref mut v) = unsafe {
1416+
self.table
1417+
.insert(hash, (key, value), |x| hasher(&x.0))
1418+
.as_mut()
1419+
};
14141420
(k, v)
14151421
}
14161422

0 commit comments

Comments
 (0)