@@ -195,8 +195,8 @@ impl ProbeSeq {
195195fn capacity_to_buckets ( cap : usize , table_layout : TableLayout ) -> Option < usize > {
196196 debug_assert_ne ! ( cap, 0 ) ;
197197
198- // Consider a small layout like TableLayout { size: 1, ctrl_align: 16 } on
199- // a platform with Group::WIDTH of 16 (like x86_64 with SSE2). For small
198+ // Consider a small TableLayout like { size: 1, ctrl_align: 16 } on a
199+ // platform with Group::WIDTH of 16 (like x86_64 with SSE2). For small
200200 // bucket sizes, this ends up wasting quite a few bytes just to pad to the
201201 // relatively larger ctrl_align:
202202 //
@@ -208,16 +208,19 @@ fn capacity_to_buckets(cap: usize, table_layout: TableLayout) -> Option<usize> {
208208 // | 28 | 32 | 80 | 3.3 |
209209 //
210210 // In general, buckets * table_layout.size >= table_layout.ctrl_align must
211- // be true to avoid these edges.
212- let min_buckets = table_layout. ctrl_align / table_layout. size . max ( 1 ) ;
213-
214- // This `min_buckets * 7 / 8` is the reverse of the `cap * 8 / 7` below.
215- let min_cap = match min_buckets. checked_mul ( 7 ) {
216- Some ( c) => cap. max ( c / 8 ) ,
217- None => cap,
218- } ;
219-
220- let cap = cap. max ( min_cap) ;
211+ // be true to avoid these edges. This is implemented by adjusting the
212+ // minimum capacity upwards for small items. This code only needs to handle
213+ // ctrl_align which are less than or equal to Group::WIDTH, because valid
214+ // layout sizes are always a multiple of the alignment, so anything with
215+ // alignment over the Group::WIDTH won't hit this edge case.
216+ let cap = cap. max ( match ( Group :: WIDTH , table_layout. size ) {
217+ ( 16 , 0 ..=1 ) => 14 ,
218+ ( 16 , 2 ..=3 ) | ( 8 , 0 ..=1 ) => 7 ,
219+ _ => 3 ,
220+ } ) ;
221+
222+ // For small tables we require at least 1 empty bucket so that lookups are
223+ // guaranteed to terminate if an element doesn't exist in the table.
221224 if cap < 8 {
222225 // We don't bother with a table size of 2 buckets since that can only
223226 // hold a single element. Instead, skip directly to a 4 bucket table
0 commit comments