Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
add slice_unchecked
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Sep 23, 2021
1 parent cfc6ae2 commit 82e4fb2
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 19 deletions.
23 changes: 21 additions & 2 deletions src/array/binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,24 @@ impl<O: Offset> BinaryArray<O> {
/// # Panics
/// iff `offset + length > self.len()`.
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
let offsets = self.offsets.clone().slice(offset, length + 1);
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Creates a new [`BinaryArray`] by slicing this [`BinaryArray`].
/// # Implementation
/// This function is `O(1)`: all data will be shared between both arrays.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
let offsets = self.offsets.clone().slice_unchecked(offset, length + 1);
Self {
data_type: self.data_type.clone(),
offsets,
Expand Down Expand Up @@ -175,6 +191,9 @@ impl<O: Offset> Array for BinaryArray<O> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
25 changes: 23 additions & 2 deletions src/array/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,27 @@ impl BooleanArray {
/// This function panics iff `offset + length >= self.len()`.
#[inline]
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Returns a slice of this [`BooleanArray`].
/// # Implementation
/// This operation is `O(1)` as it amounts to increase two ref counts.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
#[inline]
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
Self {
data_type: self.data_type.clone(),
values: self.values.clone().slice(offset, length),
values: self.values.clone().slice_unchecked(offset, length),
validity,
offset: self.offset + offset,
}
Expand Down Expand Up @@ -130,6 +147,10 @@ impl Array for BooleanArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
#[inline]
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
15 changes: 15 additions & 0 deletions src/array/dictionary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ impl<K: DictionaryKey> DictionaryArray<K> {
}

/// Creates a new [`DictionaryArray`] by slicing the existing [`DictionaryArray`].
/// # Panics
/// iff `offset + length > self.len()`.
pub fn slice(&self, offset: usize, length: usize) -> Self {
Self {
data_type: self.data_type.clone(),
Expand All @@ -83,6 +85,16 @@ impl<K: DictionaryKey> DictionaryArray<K> {
}
}

/// Creates a new [`DictionaryArray`] by slicing the existing [`DictionaryArray`].
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
Self {
data_type: self.data_type.clone(),
keys: self.keys.clone().slice_unchecked(offset, length),
values: self.values.clone(),
offset: self.offset + offset,
}
}

/// Sets the validity bitmap on this [`Array`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
Expand Down Expand Up @@ -149,6 +161,9 @@ impl<K: DictionaryKey> Array for DictionaryArray<K> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
25 changes: 23 additions & 2 deletions src/array/fixed_size_binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,30 @@ impl FixedSizeBinaryArray {
/// Returns a slice of this [`FixedSizeBinaryArray`].
/// # Implementation
/// This operation is `O(1)` as it amounts to increase 3 ref counts.
/// # Panics
/// panics iff `offset + length >= self.len()`
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Returns a slice of this [`FixedSizeBinaryArray`].
/// # Implementation
/// This operation is `O(1)` as it amounts to increase 3 ref counts.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
let values = self
.values
.clone()
.slice(offset * self.size as usize, length * self.size as usize);
.slice_unchecked(offset * self.size as usize, length * self.size as usize);
Self {
data_type: self.data_type.clone(),
size: self.size,
Expand Down Expand Up @@ -139,6 +157,9 @@ impl Array for FixedSizeBinaryArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
25 changes: 23 additions & 2 deletions src/array/fixed_size_list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,30 @@ impl FixedSizeListArray {
/// Returns a slice of this [`FixedSizeListArray`].
/// # Implementation
/// This operation is `O(1)`.
/// # Panics
/// panics iff `offset + length >= self.len()`
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Returns a slice of this [`FixedSizeListArray`].
/// # Implementation
/// This operation is `O(1)`.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
let values = self
.values
.clone()
.slice(offset * self.size as usize, length * self.size as usize)
.slice_unchecked(offset * self.size as usize, length * self.size as usize)
.into();
Self {
data_type: self.data_type.clone(),
Expand Down Expand Up @@ -143,6 +161,9 @@ impl Array for FixedSizeListArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
24 changes: 22 additions & 2 deletions src/array/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,26 @@ impl<O: Offset> ListArray<O> {
self.values.slice(offset.to_usize(), length)
}

/// Returns a slice of this [`ListArray`].
/// # Panics
/// panics iff `offset + length >= self.len()`
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
let offsets = self.offsets.clone().slice(offset, length + 1);
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Returns a slice of this [`ListArray`].
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
let offsets = self.offsets.clone().slice_unchecked(offset, length + 1);
Self {
data_type: self.data_type.clone(),
offsets,
Expand Down Expand Up @@ -186,6 +203,9 @@ impl<O: Offset> Array for ListArray<O> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
8 changes: 8 additions & 0 deletions src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ pub trait Array: std::fmt::Debug + Send + Sync {
/// This function panics iff `offset + length >= self.len()`.
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array>;

/// Slices the [`Array`], returning a new `Box<dyn Array>`.
/// # Implementation
/// This operation is `O(1)` over `len`, as it amounts to increase two ref counts
/// and moving the struct to the heap.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array>;

/// Sets the validity bitmap on this [`Array`].
/// # Panic
/// This function panics iff `validity.len() < self.len()`.
Expand Down
3 changes: 3 additions & 0 deletions src/array/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ impl Array for NullArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, _: Option<Bitmap>) -> Box<dyn Array> {
panic!("cannot set validity of a null array")
}
Expand Down
24 changes: 22 additions & 2 deletions src/array/primitive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,27 @@ impl<T: NativeType> PrimitiveArray<T> {
/// This function panics iff `offset + length >= self.len()`.
#[inline]
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
assert!(
offset + length <= self.len(),
"offset + length may not exceed length of array"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Returns a slice of this [`PrimitiveArray`].
/// # Implementation
/// This operation is `O(1)` as it amounts to increase two ref counts.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
#[inline]
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
Self {
data_type: self.data_type.clone(),
values: self.values.clone().slice(offset, length),
values: self.values.clone().slice_unchecked(offset, length),
validity,
offset: self.offset + offset,
}
Expand Down Expand Up @@ -176,6 +193,9 @@ impl<T: NativeType> Array for PrimitiveArray<T> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
23 changes: 21 additions & 2 deletions src/array/struct_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,29 @@ impl StructArray {
/// # Implementation
/// This operation is `O(F)` where `F` is the number of fields.
pub fn slice(&self, offset: usize, length: usize) -> Self {
let validity = self.validity.clone().map(|x| x.slice(offset, length));
assert!(
offset + length <= self.len(),
"offset + length may not exceed length of array"
);
unsafe { self.slice_unchecked(offset, length) }
}

/// Creates a new [`StructArray`] that is a slice of `self`.
/// # Implementation
/// This operation is `O(F)` where `F` is the number of fields.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|x| x.slice_unchecked(offset, length));
Self {
data_type: self.data_type.clone(),
values: self
.values
.iter()
.map(|x| x.slice(offset, length).into())
.map(|x| x.slice_unchecked(offset, length).into())
.collect(),
validity,
}
Expand Down Expand Up @@ -175,6 +191,9 @@ impl Array for StructArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
Expand Down
20 changes: 20 additions & 0 deletions src/array/union/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ impl UnionArray {
offset: self.offset + offset,
}
}

/// Returns a slice of this [`UnionArray`].
/// # Implementation
/// This operation is `O(F)` where `F` is the number of fields.
/// # Safety
/// The caller must ensure that `offset + length < self.len()`.
#[inline]
pub unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
Self {
data_type: self.data_type.clone(),
fields: self.fields.clone(),
fields_hash: self.fields_hash.clone(),
types: self.types.clone().slice_unchecked(offset, length),
offsets: self.offsets.clone(),
offset: self.offset + offset,
}
}
}

impl Array for UnionArray {
Expand All @@ -212,6 +229,9 @@ impl Array for UnionArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice_unchecked(offset, length))
}
fn with_validity(&self, _: Option<Bitmap>) -> Box<dyn Array> {
panic!("cannot set validity of a union array")
}
Expand Down
Loading

0 comments on commit 82e4fb2

Please sign in to comment.