@@ -176,6 +176,37 @@ impl MutableBuffer {
176176 self . len = new_len;
177177 }
178178
179+ /// Shrinks the capacity of the buffer as much as possible.
180+ /// The new capacity will aligned to the nearest 64 bit alignment.
181+ ///
182+ /// # Example
183+ /// ```
184+ /// # use arrow::buffer::{Buffer, MutableBuffer};
185+ /// // 2 cache lines
186+ /// let mut buffer = MutableBuffer::new(128);
187+ /// assert_eq!(buffer.capacity(), 128);
188+ /// buffer.push(1);
189+ /// buffer.push(2);
190+ ///
191+ /// buffer.shrink_to_fit();
192+ /// assert!(buffer.capacity() >= 64 && buffer.capacity() < 128);
193+ /// ```
194+ pub fn shrink_to_fit ( & mut self ) {
195+ let new_capacity = bit_util:: round_upto_multiple_of_64 ( self . len ) ;
196+ if new_capacity < self . capacity {
197+ // JUSTIFICATION
198+ // Benefit
199+ // necessity
200+ // Soundness
201+ // `self.data` is valid for `self.capacity`.
202+ let ptr =
203+ unsafe { alloc:: reallocate ( self . data , self . capacity , new_capacity) } ;
204+
205+ self . data = ptr;
206+ self . capacity = new_capacity;
207+ }
208+ }
209+
179210 /// Returns whether this buffer is empty or not.
180211 #[ inline]
181212 pub const fn is_empty ( & self ) -> bool {
@@ -746,4 +777,15 @@ mod tests {
746777 buf2. reserve ( 65 ) ;
747778 assert ! ( buf != buf2) ;
748779 }
780+
781+ #[ test]
782+ fn test_mutable_shrink_to_fit ( ) {
783+ let mut buffer = MutableBuffer :: new ( 128 ) ;
784+ assert_eq ! ( buffer. capacity( ) , 128 ) ;
785+ buffer. push ( 1 ) ;
786+ buffer. push ( 2 ) ;
787+
788+ buffer. shrink_to_fit ( ) ;
789+ assert ! ( buffer. capacity( ) >= 64 && buffer. capacity( ) < 128 ) ;
790+ }
749791}
0 commit comments