@@ -222,12 +222,83 @@ impl<H, T> HeaderVec<H, T> {
222
222
self . ptr = weak. ptr ;
223
223
}
224
224
225
+ /// Reserves capacity for at least `additional` more elements to be inserted in the given `HeaderVec`.
226
+ #[ inline( always) ]
227
+ pub fn reserve ( & mut self , additional : usize ) -> Option < * const ( ) > {
228
+ if self . spare_capacity ( ) < additional {
229
+ let len = self . len_exact ( ) ;
230
+ unsafe { self . resize_cold ( len + additional, false ) }
231
+ } else {
232
+ None
233
+ }
234
+ }
235
+
236
+ /// Reserves capacity for exactly `additional` more elements to be inserted in the given `HeaderVec`.
237
+ #[ inline]
238
+ pub fn reserve_exact ( & mut self , additional : usize ) -> Option < * const ( ) > {
239
+ if self . spare_capacity ( ) < additional {
240
+ let len = self . len_exact ( ) ;
241
+ unsafe { self . resize_cold ( len + additional, true ) }
242
+ } else {
243
+ None
244
+ }
245
+ }
246
+
247
+ /// Shrinks the capacity of the `HeaderVec` to the `min_capacity` or `self.len()`, whichever is larger.
248
+ #[ inline]
249
+ pub fn shrink_to ( & mut self , min_capacity : usize ) -> Option < * const ( ) > {
250
+ let requested_capacity = self . len_exact ( ) . max ( min_capacity) ;
251
+ unsafe { self . resize_cold ( requested_capacity, true ) }
252
+ }
253
+
254
+ /// Resizes the vector hold exactly `self.len()` elements.
255
+ #[ inline( always) ]
256
+ pub fn shrink_to_fit ( & mut self ) -> Option < * const ( ) > {
257
+ let len = self . len_exact ( ) ;
258
+ self . shrink_to ( len)
259
+ }
260
+
261
+ /// Resize the vector to have at least room for `additional` more elements.
262
+ /// does exact resizing if `exact` is true.
263
+ ///
264
+ /// Returns `Some(*const ())` if the memory was moved to a new location.
265
+ ///
266
+ /// # Safety
267
+ ///
268
+ /// `requested_capacity` must be greater or equal than `self.len()`
225
269
#[ cold]
226
- fn resize_insert ( & mut self ) -> Option < * const ( ) > {
270
+ unsafe fn resize_cold ( & mut self , requested_capacity : usize , exact : bool ) -> Option < * const ( ) > {
271
+ // For efficiency we do only a debug_assert here
272
+ debug_assert ! (
273
+ self . len_exact( ) <= requested_capacity,
274
+ "requested capacity is less than current length"
275
+ ) ;
227
276
let old_capacity = self . capacity ( ) ;
228
- let new_capacity = old_capacity * 2 ;
229
- // Set the new capacity.
230
- self . header_mut ( ) . capacity = new_capacity;
277
+ debug_assert_ne ! ( old_capacity, 0 , "capacity of 0 not yet supported" ) ;
278
+ debug_assert_ne ! ( requested_capacity, 0 , "capacity of 0 not yet supported" ) ;
279
+
280
+ let new_capacity = if requested_capacity > old_capacity {
281
+ if exact {
282
+ // exact growing
283
+ requested_capacity
284
+ } else if requested_capacity <= old_capacity * 2 {
285
+ // doubling the capacity is sufficient
286
+ old_capacity * 2
287
+ } else {
288
+ // requested more than twice as much space, reserve the next multiple of
289
+ // old_capacity that is greater than the requested capacity. This gives headroom
290
+ // for new inserts while not doubling the memory requirement with bulk requests
291
+ ( requested_capacity / old_capacity + 1 ) . saturating_mul ( old_capacity)
292
+ }
293
+ } else if exact {
294
+ // exact shrinking
295
+ requested_capacity
296
+ } else {
297
+ unimplemented ! ( )
298
+ // or: (has no public API yet)
299
+ // // shrink to the next power of two or self.capacity, whichever is smaller
300
+ // requested_capacity.next_power_of_two().min(self.capacity())
301
+ } ;
231
302
// Reallocate the pointer.
232
303
let ptr = unsafe {
233
304
alloc:: alloc:: realloc (
@@ -249,24 +320,20 @@ impl<H, T> HeaderVec<H, T> {
249
320
} ;
250
321
// Assign the new pointer.
251
322
self . ptr = ptr;
323
+ // And set the new capacity.
324
+ self . header_mut ( ) . capacity = new_capacity;
252
325
253
326
previous_pointer
254
327
}
255
328
256
329
/// Adds an item to the end of the list.
257
330
///
258
- /// Returns `true ` if the memory was moved to a new location.
331
+ /// Returns `Some(*const ()) ` if the memory was moved to a new location.
259
332
/// In this case, you are responsible for updating the weak nodes.
260
333
pub fn push ( & mut self , item : T ) -> Option < * const ( ) > {
261
334
let old_len = self . len_exact ( ) ;
262
335
let new_len = old_len + 1 ;
263
- let old_capacity = self . capacity ( ) ;
264
- // If it isn't big enough.
265
- let previous_pointer = if new_len > old_capacity {
266
- self . resize_insert ( )
267
- } else {
268
- None
269
- } ;
336
+ let previous_pointer = self . reserve ( 1 ) ;
270
337
unsafe {
271
338
core:: ptr:: write ( self . start_ptr_mut ( ) . add ( old_len) , item) ;
272
339
}
0 commit comments