This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new 0b4c80c85 Add vec-inspired APIs to BufferBuilder (#1850) (#1860)
0b4c80c85 is described below
commit 0b4c80c8587f18260d624d2e5ac580669d96db86
Author: Raphael Taylor-Davies <[email protected]>
AuthorDate: Wed Jun 15 14:18:28 2022 +0100
Add vec-inspired APIs to BufferBuilder (#1850) (#1860)
---
arrow/src/array/builder.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++-
arrow/src/buffer/mutable.rs | 15 ++++++++
2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/arrow/src/array/builder.rs b/arrow/src/array/builder.rs
index 041b7a92c..ed26d3c2f 100644
--- a/arrow/src/array/builder.rs
+++ b/arrow/src/array/builder.rs
@@ -180,8 +180,7 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
/// ```
#[inline]
pub fn advance(&mut self, i: usize) {
- let new_buffer_len = (self.len + i) * mem::size_of::<T>();
- self.buffer.resize(new_buffer_len, 0);
+ self.buffer.extend_zeros(i * mem::size_of::<T>());
self.len += i;
}
@@ -244,6 +243,24 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
self.len += n;
}
+ /// Appends `n`, zero-initialized values
+ ///
+ /// # Example:
+ ///
+ /// ```
+ /// use arrow::array::UInt32BufferBuilder;
+ ///
+ /// let mut builder = UInt32BufferBuilder::new(10);
+ /// builder.append_n_zeroed(3);
+ ///
+ /// assert_eq!(builder.len(), 3);
+ /// assert_eq!(builder.as_slice(), &[0, 0, 0])
+ #[inline]
+ pub fn append_n_zeroed(&mut self, n: usize) {
+ self.buffer.extend_zeros(n * mem::size_of::<T>());
+ self.len += n;
+ }
+
/// Appends a slice of type `T`, growing the internal buffer as needed.
///
/// # Example:
@@ -262,6 +279,78 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
self.len += slice.len();
}
+ /// View the contents of this buffer as a slice
+ ///
+ /// ```
+ /// use arrow::array::Float64BufferBuilder;
+ ///
+ /// let mut builder = Float64BufferBuilder::new(10);
+ /// builder.append(1.3);
+ /// builder.append_n(2, 2.3);
+ ///
+ /// assert_eq!(builder.as_slice(), &[1.3, 2.3, 2.3]);
+ /// ```
+ #[inline]
+ pub fn as_slice(&self) -> &[T] {
+ // SAFETY
+ //
+ // - MutableBuffer is aligned and initialized for len elements of T
+ // - MutableBuffer corresponds to a single allocation
+ // - MutableBuffer does not support modification whilst active
immutable borrows
+ unsafe { std::slice::from_raw_parts(self.buffer.as_ptr() as _,
self.len) }
+ }
+
+ /// View the contents of this buffer as a mutable slice
+ ///
+ /// # Example:
+ ///
+ /// ```
+ /// use arrow::array::Float32BufferBuilder;
+ ///
+ /// let mut builder = Float32BufferBuilder::new(10);
+ ///
+ /// builder.append_slice(&[1., 2., 3.4]);
+ /// assert_eq!(builder.as_slice(), &[1., 2., 3.4]);
+ ///
+ /// builder.as_slice_mut()[1] = 4.2;
+ /// assert_eq!(builder.as_slice(), &[1., 4.2, 3.4]);
+ /// ```
+ #[inline]
+ pub fn as_slice_mut(&mut self) -> &mut [T] {
+ // SAFETY
+ //
+ // - MutableBuffer is aligned and initialized for len elements of T
+ // - MutableBuffer corresponds to a single allocation
+ // - MutableBuffer does not support modification whilst active
immutable borrows
+ unsafe { std::slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as _,
self.len) }
+ }
+
+ /// Shorten this BufferBuilder to `len` items
+ ///
+ /// If `len` is greater than the builder's current length, this has no
effect
+ ///
+ /// # Example:
+ ///
+ /// ```
+ /// use arrow::array::UInt16BufferBuilder;
+ ///
+ /// let mut builder = UInt16BufferBuilder::new(10);
+ ///
+ /// builder.append_slice(&[42, 44, 46]);
+ /// assert_eq!(builder.as_slice(), &[42, 44, 46]);
+ ///
+ /// builder.truncate(2);
+ /// assert_eq!(builder.as_slice(), &[42, 44]);
+ ///
+ /// builder.append(12);
+ /// assert_eq!(builder.as_slice(), &[42, 44, 12]);
+ /// ```
+ #[inline]
+ pub fn truncate(&mut self, len: usize) {
+ self.buffer.truncate(len * mem::size_of::<T>());
+ self.len = len;
+ }
+
/// # Safety
/// This requires the iterator be a trusted length. This could instead
require
/// the iterator implement `TrustedLen` once that is stabilized.
diff --git a/arrow/src/buffer/mutable.rs b/arrow/src/buffer/mutable.rs
index 709973b44..ef3e35209 100644
--- a/arrow/src/buffer/mutable.rs
+++ b/arrow/src/buffer/mutable.rs
@@ -30,7 +30,11 @@ use std::ptr::NonNull;
/// along cache lines and in multiple of 64 bytes.
/// Use [MutableBuffer::push] to insert an item,
[MutableBuffer::extend_from_slice]
/// to insert many items, and `into` to convert it to [`Buffer`].
+///
+/// For a safe, strongly typed API consider using
[`crate::array::BufferBuilder`]
+///
/// # Example
+///
/// ```
/// # use arrow::buffer::{Buffer, MutableBuffer};
/// let mut buffer = MutableBuffer::new(0);
@@ -152,6 +156,17 @@ impl MutableBuffer {
}
}
+ /// Truncates this buffer to `len` bytes
+ ///
+ /// If `len` is greater than the buffer's current length, this has no
effect
+ #[inline(always)]
+ pub fn truncate(&mut self, len: usize) {
+ if len > self.len {
+ return;
+ }
+ self.len = len;
+ }
+
/// Resizes the buffer, either truncating its contents (with no change in
capacity), or
/// growing it (potentially reallocating it) and writing `value` in the
newly available bytes.
/// # Example