Skip to content

Commit 7f37a7f

Browse files
authored
Mutablebuffer::shrink_to_fit (#318)
* Mutablebuffer::shrink_to_fit * add shrink_to_fit explicit test
1 parent c863a2c commit 7f37a7f

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

arrow/src/buffer/mutable.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)