@@ -1045,18 +1045,15 @@ impl<T, A: Allocator> RawTable<T, A> {
10451045 )
10461046 }
10471047
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 > {
10531050 unsafe {
10541051 // SAFETY:
10551052 // 1. The [`RawTableInner`] must already have properly initialized control bytes since
10561053 // we will never expose `RawTable::new_uninitialized` in a public API.
10571054 //
10581055 // 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) ;
10601057
10611058 // We can avoid growing the table once we have reached our load factor if we are replacing
10621059 // 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> {
10651062 // in the range `0..=self.buckets()`.
10661063 let old_ctrl = * self . table . ctrl ( slot. index ) ;
10671064 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 => {
10681079 self . reserve ( 1 , hasher) ;
10691080 // SAFETY: We know for sure that `RawTableInner` has control bytes
10701081 // 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) }
10721083 }
1084+ Some ( slot) => slot,
1085+ } ;
1086+ // SAFETY: todo
1087+ unsafe { self . insert_in_slot ( hash, slot, value) }
1088+ }
10731089
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) } )
10761099 }
10771100
10781101 /// Inserts a new element into the table, and returns a mutable reference to it.
0 commit comments