Skip to content
This repository has been archived by the owner on Nov 12, 2023. It is now read-only.

Commit

Permalink
upgrade to arrow2 v0.17 (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
nmandery authored Jul 4, 2023
1 parent ff1f840 commit fefafeb
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 307 deletions.
52 changes: 4 additions & 48 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ geos = { version = "8", features = ["v3_8_0", "geo"], optional = true }
thiserror = "1"
anyhow = "1"
geozero = { version = "0.9.4", features = ["with-wkb"] }
arrow2 = { version = "0.15" }
arrow2 = { version = "0.17" }
# TODO: properly feature gate this
rstar = { version = "0.9.3" }

[dev-dependencies]
arrow2 = { version = "0.15", features = [
arrow2 = { version = "0.17", features = [
"io_parquet",
"io_parquet_compression",
] }
Expand Down
19 changes: 8 additions & 11 deletions src/binary/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,24 @@ impl<'a> GeometryArrayTrait<'a> for WKBArray {
///
/// let array = PrimitiveArray::from_vec(vec![1, 2, 3]);
/// assert_eq!(format!("{:?}", array), "Int32[1, 2, 3]");
/// let sliced = array.slice(1, 1);
/// assert_eq!(format!("{:?}", sliced), "Int32[2]");
/// // note: `sliced` and `array` share the same memory region.
/// array.slice(1, 1);
/// assert_eq!(format!("{:?}", array), "Int32[2]");
/// ```
/// # Panic
/// This function panics iff `offset + length > self.len()`.
#[inline]
#[must_use]
fn slice(&self, offset: usize, length: usize) -> Self {
WKBArray(self.0.slice(offset, length))
fn slice(&mut self, offset: usize, length: usize) {
self.0.slice(offset, length);
}

/// Returns a clone of this [`PrimitiveArray`] sliced by an offset and length.
/// Slices this [`PrimitiveArray`] by an offset and length.
/// # Implementation
/// This operation is `O(1)` as it amounts to increase two ref counts.
/// This operation is `O(1)`.
/// # Safety
/// The caller must ensure that `offset + length <= self.len()`.
#[inline]
#[must_use]
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
WKBArray(self.0.slice_unchecked(offset, length))
unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
self.0.slice_unchecked(offset, length);
}

fn to_boxed(&self) -> Box<Self> {
Expand Down
56 changes: 21 additions & 35 deletions src/enum_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ impl<'a> GeometryArrayTrait<'a> for GeometryArray {
fn rstar_tree(&'a self) -> rstar::RTree<Self::Scalar> {
let mut tree = RTree::new();
(0..self.len())
.into_iter()
.filter_map(|geom_idx| self.get(geom_idx))
.for_each(|geom| tree.insert(geom));
tree
Expand Down Expand Up @@ -171,53 +170,40 @@ impl<'a> GeometryArrayTrait<'a> for GeometryArray {
}
}

/// Slices the [`GeometryArray`], returning a new [`GeometryArray`].
/// Slices the [`GeometryArray`] in plave.
/// # Implementation
/// This operation is `O(1)` over `len`, as it amounts to increase two ref counts
/// and moving the struct to the heap.
/// # Panic
/// This function panics iff `offset + length > self.len()`.
fn slice(&self, offset: usize, length: usize) -> GeometryArray {
fn slice(&mut self, offset: usize, length: usize) {
match self {
GeometryArray::Point(arr) => GeometryArray::Point(arr.slice(offset, length)),
GeometryArray::LineString(arr) => GeometryArray::LineString(arr.slice(offset, length)),
GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.slice(offset, length)),
GeometryArray::MultiPoint(arr) => GeometryArray::MultiPoint(arr.slice(offset, length)),
GeometryArray::MultiLineString(arr) => {
GeometryArray::MultiLineString(arr.slice(offset, length))
}
GeometryArray::MultiPolygon(arr) => {
GeometryArray::MultiPolygon(arr.slice(offset, length))
}
GeometryArray::WKB(arr) => GeometryArray::WKB(arr.slice(offset, length)),
}
GeometryArray::Point(arr) => arr.slice(offset, length),
GeometryArray::LineString(arr) => arr.slice(offset, length),
GeometryArray::Polygon(arr) => arr.slice(offset, length),
GeometryArray::MultiPoint(arr) => arr.slice(offset, length),
GeometryArray::MultiLineString(arr) => arr.slice(offset, length),
GeometryArray::MultiPolygon(arr) => arr.slice(offset, length),
GeometryArray::WKB(arr) => arr.slice(offset, length),
};
}

/// Slices the [`GeometryArray`], returning a new [`GeometryArray`].
/// Slices the [`GeometryArray`] in place.
/// # Implementation
/// This operation is `O(1)` over `len`, as it amounts to increase two ref counts
/// and moving the struct to the heap.
/// This operation is `O(1)` over `len`.
/// # Safety
/// The caller must ensure that `offset + length <= self.len()`
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> GeometryArray {
unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
match self {
GeometryArray::Point(arr) => GeometryArray::Point(arr.slice_unchecked(offset, length)),
GeometryArray::LineString(arr) => {
GeometryArray::LineString(arr.slice_unchecked(offset, length))
}
GeometryArray::Polygon(arr) => {
GeometryArray::Polygon(arr.slice_unchecked(offset, length))
}
GeometryArray::MultiPoint(arr) => {
GeometryArray::MultiPoint(arr.slice_unchecked(offset, length))
}
GeometryArray::MultiLineString(arr) => {
GeometryArray::MultiLineString(arr.slice_unchecked(offset, length))
}
GeometryArray::MultiPolygon(arr) => {
GeometryArray::MultiPolygon(arr.slice_unchecked(offset, length))
GeometryArray::Point(arr) => arr.slice_unchecked(offset, length),
GeometryArray::LineString(arr) => arr.slice_unchecked(offset, length),
GeometryArray::Polygon(arr) => arr.slice_unchecked(offset, length),
GeometryArray::MultiPoint(arr) => arr.slice_unchecked(offset, length),
GeometryArray::MultiLineString(arr) => arr.slice_unchecked(offset, length),
GeometryArray::MultiPolygon(arr) => arr.slice_unchecked(offset, length),
GeometryArray::WKB(arr) => {
arr.slice_unchecked(offset, length);
}
GeometryArray::WKB(arr) => GeometryArray::WKB(arr.slice_unchecked(offset, length)),
}
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ pub mod multipoint;
pub mod multipolygon;
pub mod point;
pub mod polygon;
mod slice;
pub mod trait_;
53 changes: 18 additions & 35 deletions src/linestring/array.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::error::GeoArrowError;
use crate::slice::slice_validity_unchecked;
use crate::{GeometryArrayTrait, MultiPointArray};
use arrow2::array::{Array, ListArray, PrimitiveArray, StructArray};
use arrow2::bitmap::utils::{BitmapIter, ZipValidity};
Expand Down Expand Up @@ -35,7 +36,7 @@ pub(super) fn check(
geom_offsets: &OffsetsBuffer<i64>,
) -> Result<(), GeoArrowError> {
// TODO: check geom offsets?
if validity_len.map_or(false, |len| len != geom_offsets.len()) {
if validity_len.map_or(false, |len| len != geom_offsets.len_proxy()) {
return Err(GeoArrowError::General(
"validity mask length must match the number of values".to_string(),
));
Expand Down Expand Up @@ -139,7 +140,7 @@ impl<'a> GeometryArrayTrait<'a> for LineStringArray {
/// Returns the number of geometries in this array
#[inline]
fn len(&self) -> usize {
self.geom_offsets.len()
self.geom_offsets.len_proxy()
}

/// Returns the optional validity.
Expand All @@ -148,56 +149,38 @@ impl<'a> GeometryArrayTrait<'a> for LineStringArray {
self.validity.as_ref()
}

/// Returns a clone of this [`PrimitiveArray`] sliced by an offset and length.
/// Slices this [`PrimitiveArray`] in place.
/// # Implementation
/// This operation is `O(1)` as it amounts to increase two ref counts.
/// This operation is `O(1)`.
/// # Examples
/// ```
/// use arrow2::array::PrimitiveArray;
///
/// let array = PrimitiveArray::from_vec(vec![1, 2, 3]);
/// assert_eq!(format!("{:?}", array), "Int32[1, 2, 3]");
/// let sliced = array.slice(1, 1);
/// assert_eq!(format!("{:?}", sliced), "Int32[2]");
/// // note: `sliced` and `array` share the same memory region.
/// array.slice(1, 1);
/// assert_eq!(format!("{:?}", array), "Int32[2]");
/// ```
/// # Panic
/// This function panics iff `offset + length > self.len()`.
#[inline]
#[must_use]
fn slice(&self, offset: usize, length: usize) -> Self {
fn slice(&mut self, offset: usize, length: usize) {
assert!(
offset + length <= self.len(),
"offset + length may not exceed length of array"
);
unsafe { self.slice_unchecked(offset, length) }
unsafe { self.slice_unchecked(offset, length) };
}

/// Returns a clone of this [`PrimitiveArray`] sliced by an offset and length.
/// Slices this [`PrimitiveArray`] in place.
/// # Implementation
/// This operation is `O(1)` as it amounts to increase two ref counts.
/// This operation is `O(1)`.
/// # Safety
/// The caller must ensure that `offset + length <= self.len()`.
#[inline]
#[must_use]
unsafe fn slice_unchecked(&self, offset: usize, length: usize) -> Self {
let validity = self
.validity
.clone()
.map(|bitmap| bitmap.slice_unchecked(offset, length))
.and_then(|bitmap| (bitmap.unset_bits() > 0).then_some(bitmap));

let geom_offsets = self
.geom_offsets
.clone()
.slice_unchecked(offset, length + 1);

Self {
x: self.x.clone(),
y: self.y.clone(),
geom_offsets,
validity,
}
unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
slice_validity_unchecked(&mut self.validity, offset, length);
self.geom_offsets.slice_unchecked(offset, length + 1);
}

fn to_boxed(&self) -> Box<Self> {
Expand Down Expand Up @@ -403,9 +386,9 @@ mod test {

#[test]
fn slice() {
let arr: LineStringArray = vec![ls0(), ls1()].into();
let sliced = arr.slice(1, 1);
assert_eq!(sliced.len(), 1);
assert_eq!(sliced.get_as_geo(0), Some(ls1()));
let mut arr: LineStringArray = vec![ls0(), ls1()].into();
arr.slice(1, 1);
assert_eq!(arr.len(), 1);
assert_eq!(arr.get_as_geo(0), Some(ls1()));
}
}
Loading

0 comments on commit fefafeb

Please sign in to comment.