File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -91,6 +91,19 @@ fn insert(c: &mut Criterion) {
9191 } ) ;
9292}
9393
94+ fn grow_and_insert ( c : & mut Criterion ) {
95+ const N : usize = 1_000_000 ;
96+ let mut fb = FixedBitSet :: with_capacity ( N ) ;
97+
98+ c. bench_function ( "grow_and_insert" , |b| {
99+ b. iter ( || {
100+ for i in 0 ..N {
101+ fb. grow_and_insert ( i) ;
102+ }
103+ } )
104+ } ) ;
105+ }
106+
94107fn union_with ( c : & mut Criterion ) {
95108 const N : usize = 1_000_000 ;
96109 let mut fb_a = FixedBitSet :: with_capacity ( N ) ;
@@ -159,5 +172,6 @@ criterion_group!(
159172 symmetric_difference_with,
160173 count_ones,
161174 clear,
175+ grow_and_insert,
162176) ;
163177criterion_main ! ( benches) ;
Original file line number Diff line number Diff line change @@ -123,6 +123,22 @@ impl FixedBitSet {
123123 }
124124 }
125125
126+ /// Grows the internal size of the bitset before inserting a bit
127+ ///
128+ /// Unlike `insert`, this cannot panic, but may allocate if the bit is outside of the existing buffer's range.
129+ ///
130+ /// This is faster than calling `grow` then `insert` in succession.
131+ #[ inline]
132+ pub fn grow_and_insert ( & mut self , bits : usize ) {
133+ self . grow ( bits + 1 ) ;
134+
135+ let ( blocks, rem) = div_rem ( bits) ;
136+ // SAFETY: The above grow ensures that the block is inside the Vec's allocation.
137+ unsafe {
138+ * self . data . get_unchecked_mut ( blocks) |= 1 << rem;
139+ }
140+ }
141+
126142 /// The length of the [`FixedBitSet`] in bits.
127143 ///
128144 /// Note: `len` includes both set and unset bits.
@@ -1043,6 +1059,18 @@ mod tests {
10431059 assert ! ( fb. contains( 64 ) ) ;
10441060 }
10451061
1062+ #[ test]
1063+ fn grow_and_insert ( ) {
1064+ let mut fb = FixedBitSet :: default ( ) ;
1065+ for i in 0 ..100 {
1066+ if i % 3 == 0 {
1067+ fb. grow_and_insert ( i) ;
1068+ }
1069+ }
1070+
1071+ assert_eq ! ( fb. count_ones( ..) , 34 ) ;
1072+ }
1073+
10461074 #[ test]
10471075 fn test_toggle ( ) {
10481076 let mut fb = FixedBitSet :: with_capacity ( 16 ) ;
You can’t perform that action at this time.
0 commit comments