@@ -222,12 +222,83 @@ impl<H, T> HeaderVec<H, T> {
222222 self . ptr = weak. ptr ;
223223 }
224224
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()`
225269 #[ 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+ ) ;
227276 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+ } ;
231302 // Reallocate the pointer.
232303 let ptr = unsafe {
233304 alloc:: alloc:: realloc (
@@ -249,24 +320,20 @@ impl<H, T> HeaderVec<H, T> {
249320 } ;
250321 // Assign the new pointer.
251322 self . ptr = ptr;
323+ // And set the new capacity.
324+ self . header_mut ( ) . capacity = new_capacity;
252325
253326 previous_pointer
254327 }
255328
256329 /// Adds an item to the end of the list.
257330 ///
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.
259332 /// In this case, you are responsible for updating the weak nodes.
260333 pub fn push ( & mut self , item : T ) -> Option < * const ( ) > {
261334 let old_len = self . len_exact ( ) ;
262335 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 ) ;
270337 unsafe {
271338 core:: ptr:: write ( self . start_ptr_mut ( ) . add ( old_len) , item) ;
272339 }
0 commit comments