@@ -1045,18 +1045,15 @@ impl<T, A: Allocator> RawTable<T, A> {
1045
1045
)
1046
1046
}
1047
1047
1048
- /// Inserts a new element into the table, and returns its raw bucket.
1049
- ///
1050
- /// This does not check if the given element already exists in the table.
1051
- #[ cfg_attr( feature = "inline-more" , inline) ]
1052
- pub fn insert ( & mut self , hash : u64 , value : T , hasher : impl Fn ( & T ) -> u64 ) -> Bucket < T > {
1048
+ #[ inline( always) ]
1049
+ fn find_insert_slot ( & self , hash : u64 ) -> Option < InsertSlot > {
1053
1050
unsafe {
1054
1051
// SAFETY:
1055
1052
// 1. The [`RawTableInner`] must already have properly initialized control bytes since
1056
1053
// we will never expose `RawTable::new_uninitialized` in a public API.
1057
1054
//
1058
1055
// 2. We reserve additional space (if necessary) right after calling this function.
1059
- let mut slot = self . table . find_insert_slot ( hash) ;
1056
+ let slot = self . table . find_insert_slot ( hash) ;
1060
1057
1061
1058
// We can avoid growing the table once we have reached our load factor if we are replacing
1062
1059
// a tombstone. This works since the number of EMPTY slots does not change in this case.
@@ -1065,14 +1062,40 @@ impl<T, A: Allocator> RawTable<T, A> {
1065
1062
// in the range `0..=self.buckets()`.
1066
1063
let old_ctrl = * self . table . ctrl ( slot. index ) ;
1067
1064
if unlikely ( self . table . growth_left == 0 && old_ctrl. special_is_empty ( ) ) {
1065
+ None
1066
+ } else {
1067
+ Some ( slot)
1068
+ }
1069
+ }
1070
+ }
1071
+
1072
+ /// Inserts a new element into the table, and returns its raw bucket.
1073
+ ///
1074
+ /// This does not check if the given element already exists in the table.
1075
+ #[ cfg_attr( feature = "inline-more" , inline) ]
1076
+ pub fn insert ( & mut self , hash : u64 , value : T , hasher : impl Fn ( & T ) -> u64 ) -> Bucket < T > {
1077
+ let slot = match self . find_insert_slot ( hash) {
1078
+ None => {
1068
1079
self . reserve ( 1 , hasher) ;
1069
1080
// SAFETY: We know for sure that `RawTableInner` has control bytes
1070
1081
// initialized and that there is extra space in the table.
1071
- slot = self . table . find_insert_slot ( hash) ;
1082
+ unsafe { self . table . find_insert_slot ( hash) }
1072
1083
}
1084
+ Some ( slot) => slot,
1085
+ } ;
1086
+ // SAFETY: todo
1087
+ unsafe { self . insert_in_slot ( hash, slot, value) }
1088
+ }
1073
1089
1074
- self . insert_in_slot ( hash, slot, value)
1075
- }
1090
+ /// Inserts a new element into the table if there is capacity, and returns
1091
+ /// its raw bucket.
1092
+ ///
1093
+ /// This does not check if the given element already exists in the table.
1094
+ #[ inline]
1095
+ pub ( crate ) fn insert_within_capacity ( & mut self , hash : u64 , value : T ) -> Option < Bucket < T > > {
1096
+ let slot = self . find_insert_slot ( hash) ?;
1097
+ // SAFETY: todo
1098
+ Some ( unsafe { self . insert_in_slot ( hash, slot, value) } )
1076
1099
}
1077
1100
1078
1101
/// Inserts a new element into the table, and returns a mutable reference to it.
0 commit comments