use arrow2::buffer::Buffer;
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ArrowBuffer<T>(pub Buffer<T>);
impl<T: crate::SizeBytes> crate::SizeBytes for ArrowBuffer<T> {
#[inline]
fn heap_size_bytes(&self) -> u64 {
let Self(buf) = self;
std::mem::size_of_val(buf.as_slice()) as _
}
}
impl<T> ArrowBuffer<T> {
#[inline]
pub fn num_instances(&self) -> usize {
self.0.len()
}
#[inline]
pub fn size_in_bytes(&self) -> usize {
self.0.len() * std::mem::size_of::<T>()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn as_slice(&self) -> &[T] {
self.0.as_slice()
}
#[inline]
pub fn into_inner(self) -> Buffer<T> {
self.0
}
#[inline]
pub fn sliced(self, range: std::ops::Range<usize>) -> Self {
Self(self.0.sliced(range.start, range.len()))
}
}
impl<T: bytemuck::Pod> ArrowBuffer<T> {
#[inline]
pub fn cast_pod<Target: bytemuck::Pod>(
&self,
) -> Result<ArrowBuffer<Target>, bytemuck::PodCastError> {
re_tracing::profile_function!();
let target_slice: &[Target] = bytemuck::try_cast_slice(self.as_slice())?;
Ok(ArrowBuffer::from(target_slice.to_vec()))
}
#[inline]
pub fn cast_to_u8(&self) -> ArrowBuffer<u8> {
match self.cast_pod() {
Ok(buf) => buf,
Err(_) => unreachable!("We can always cast POD types to u8"),
}
}
}
impl<T: Eq> Eq for ArrowBuffer<T> {}
impl<T: Clone> ArrowBuffer<T> {
#[inline]
pub fn to_vec(&self) -> Vec<T> {
self.0.as_slice().to_vec()
}
}
impl<T> From<Buffer<T>> for ArrowBuffer<T> {
#[inline]
fn from(value: Buffer<T>) -> Self {
Self(value)
}
}
impl<T> From<Vec<T>> for ArrowBuffer<T> {
#[inline]
fn from(value: Vec<T>) -> Self {
Self(value.into())
}
}
impl<T: Clone> From<&[T]> for ArrowBuffer<T> {
#[inline]
fn from(value: &[T]) -> Self {
Self(value.iter().cloned().collect()) }
}
impl<T> FromIterator<T> for ArrowBuffer<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(Buffer::from_iter(iter))
}
}
impl<T> std::ops::Deref for ArrowBuffer<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
self.0.as_slice()
}
}