use std::{iter::FromIterator, ops::Deref, sync::Arc, usize};
use either::Either;
use super::Bytes;
use super::IntoIter;
#[derive(Clone)]
pub struct Buffer<T> {
data: Arc<Bytes<T>>,
offset: usize,
length: usize,
}
impl<T: PartialEq> PartialEq for Buffer<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.deref() == other.deref()
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for Buffer<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, f)
}
}
impl<T> Default for Buffer<T> {
#[inline]
fn default() -> Self {
Vec::new().into()
}
}
impl<T> Buffer<T> {
#[inline]
pub fn new() -> Self {
Self::default()
}
pub(crate) fn from_bytes(bytes: Bytes<T>) -> Self {
let length = bytes.len();
Buffer {
data: Arc::new(bytes),
offset: 0,
length,
}
}
#[inline]
pub fn len(&self) -> usize {
self.length
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn is_sliced(&self) -> bool {
self.data.len() != self.length
}
#[inline]
pub fn as_slice(&self) -> &[T] {
debug_assert!(self.offset + self.length <= self.data.len());
unsafe {
self.data
.get_unchecked(self.offset..self.offset + self.length)
}
}
#[inline]
pub(super) unsafe fn get_unchecked(&self, index: usize) -> &T {
debug_assert!(index < self.length);
unsafe { self.data.get_unchecked(self.offset + index) }
}
#[inline]
pub fn sliced(self, offset: usize, length: usize) -> Self {
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.sliced_unchecked(offset, length) }
}
#[inline]
pub fn slice(&mut self, offset: usize, length: usize) {
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}
#[inline]
#[must_use]
pub unsafe fn sliced_unchecked(mut self, offset: usize, length: usize) -> Self {
self.slice_unchecked(offset, length);
self
}
#[inline]
pub unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
self.offset += offset;
self.length = length;
}
#[inline]
pub(crate) fn as_ptr(&self) -> *const T {
self.data.deref().as_ptr()
}
#[inline]
pub fn offset(&self) -> usize {
self.offset
}
#[inline]
pub unsafe fn set_len(&mut self, len: usize) {
self.length = len;
}
#[inline]
pub fn into_mut(mut self) -> Either<Self, Vec<T>> {
match Arc::get_mut(&mut self.data)
.and_then(|b| b.get_vec())
.map(std::mem::take)
{
Some(inner) => Either::Right(inner),
None => Either::Left(self),
}
}
#[inline]
pub unsafe fn get_mut(&mut self) -> Option<&mut Vec<T>> {
Arc::get_mut(&mut self.data).and_then(|b| b.get_vec())
}
#[inline]
pub fn get_mut_slice(&mut self) -> Option<&mut [T]> {
Arc::get_mut(&mut self.data)
.and_then(|b| b.get_vec())
.map(|x| unsafe { x.get_unchecked_mut(self.offset..self.offset + self.length) })
}
pub fn shared_count_strong(&self) -> usize {
Arc::strong_count(&self.data)
}
pub fn shared_count_weak(&self) -> usize {
Arc::weak_count(&self.data)
}
#[must_use]
pub fn into_inner(self) -> (Arc<Bytes<T>>, usize, usize) {
let Self {
data,
offset,
length,
} = self;
(data, offset, length)
}
pub unsafe fn from_inner_unchecked(data: Arc<Bytes<T>>, offset: usize, length: usize) -> Self {
Self {
data,
offset,
length,
}
}
}
impl<T> From<Vec<T>> for Buffer<T> {
#[inline]
fn from(p: Vec<T>) -> Self {
let bytes: Bytes<T> = p.into();
Self {
offset: 0,
length: bytes.len(),
data: Arc::new(bytes),
}
}
}
impl<T> std::ops::Deref for Buffer<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
self.as_slice()
}
}
impl<T> FromIterator<T> for Buffer<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Vec::from_iter(iter).into()
}
}
impl<T: Copy> IntoIterator for Buffer<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
}
#[cfg(feature = "arrow")]
impl<T: crate::types::NativeType> From<arrow_buffer::Buffer> for Buffer<T> {
fn from(value: arrow_buffer::Buffer) -> Self {
Self::from_bytes(crate::buffer::to_bytes(value))
}
}
#[cfg(feature = "arrow")]
impl<T: crate::types::NativeType> From<Buffer<T>> for arrow_buffer::Buffer {
fn from(value: Buffer<T>) -> Self {
crate::buffer::to_buffer(value.data).slice_with_length(
value.offset * std::mem::size_of::<T>(),
value.length * std::mem::size_of::<T>(),
)
}
}