@@ -374,6 +374,7 @@ impl<T> RawTable<T> {
374
374
buckets : usize ,
375
375
fallability : Fallibility ,
376
376
) -> Result < Self , CollectionAllocErr > {
377
+ debug_assert ! ( buckets. is_power_of_two( ) ) ;
377
378
let ( layout, data_offset) =
378
379
calculate_layout :: < T > ( buckets) . ok_or_else ( || fallability. capacity_overflow ( ) ) ?;
379
380
let ctrl = NonNull :: new ( alloc ( layout) ) . ok_or_else ( || fallability. alloc_err ( layout) ) ?;
@@ -452,6 +453,7 @@ impl<T> RawTable<T> {
452
453
#[ inline]
453
454
pub unsafe fn erase_no_drop ( & mut self , item : & Bucket < T > ) {
454
455
let index = self . bucket_index ( item) ;
456
+ debug_assert ! ( is_full( * self . ctrl( index) ) ) ;
455
457
let index_before = index. wrapping_sub ( Group :: WIDTH ) & self . bucket_mask ;
456
458
let empty_before = Group :: load ( self . ctrl ( index_before) ) . match_empty ( ) ;
457
459
let empty_after = Group :: load ( self . ctrl ( index) ) . match_empty ( ) ;
@@ -825,8 +827,25 @@ impl<T> RawTable<T> {
825
827
/// This does not check if the given element already exists in the table.
826
828
#[ inline]
827
829
pub fn insert ( & mut self , hash : u64 , value : T , hasher : impl Fn ( & T ) -> u64 ) -> Bucket < T > {
828
- self . reserve ( 1 , hasher) ;
829
- self . insert_no_grow ( hash, value)
830
+ unsafe {
831
+ let mut index = self . find_insert_slot ( hash) ;
832
+
833
+ // We can avoid growing the table once we have reached our load
834
+ // factor if we are replacing a tombstone. This works since the
835
+ // number of EMPTY slots does not change in this case.
836
+ let old_ctrl = * self . ctrl ( index) ;
837
+ if unlikely ( self . growth_left == 0 && special_is_empty ( old_ctrl) ) {
838
+ self . reserve ( 1 , hasher) ;
839
+ index = self . find_insert_slot ( hash) ;
840
+ }
841
+
842
+ let bucket = self . bucket ( index) ;
843
+ self . growth_left -= special_is_empty ( old_ctrl) as usize ;
844
+ self . set_ctrl ( index, h2 ( hash) ) ;
845
+ bucket. write ( value) ;
846
+ self . items += 1 ;
847
+ bucket
848
+ }
830
849
}
831
850
832
851
/// Inserts a new element into the table, without growing the table.
@@ -835,6 +854,7 @@ impl<T> RawTable<T> {
835
854
///
836
855
/// This does not check if the given element already exists in the table.
837
856
#[ inline]
857
+ #[ cfg( feature = "rustc-internal-api" ) ]
838
858
pub fn insert_no_grow ( & mut self , hash : u64 , value : T ) -> Bucket < T > {
839
859
unsafe {
840
860
let index = self . find_insert_slot ( hash) ;
0 commit comments