Skip to content

Commit

Permalink
Public from methods on mutable arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
kylebarron committed Nov 27, 2023
1 parent 8767908 commit f4830fd
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 57 deletions.
3 changes: 2 additions & 1 deletion src/array/coord/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ pub use combined::{CoordBuffer, MutableCoordBuffer};
pub use interleaved::{InterleavedCoordBuffer, MutableInterleavedCoordBuffer};
pub use separated::{MutableSeparatedCoordBuffer, SeparatedCoordBuffer};

#[derive(Debug, Clone, PartialEq)]
#[derive(Default, Debug, Clone, PartialEq)]
pub enum CoordType {
#[default]
Interleaved,
Separated,
}
94 changes: 76 additions & 18 deletions src/array/linestring/mutable.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// use super::array::check;
use crate::array::mutable_offset::OffsetsBuilder;
use crate::array::{
LineStringArray, MutableCoordBuffer, MutableInterleavedCoordBuffer, MutableMultiPointArray,
WKBArray,
CoordType, LineStringArray, MutableCoordBuffer, MutableInterleavedCoordBuffer,
MutableMultiPointArray, MutableSeparatedCoordBuffer, WKBArray,
};
use crate::error::{GeoArrowError, Result};
use crate::geo_traits::LineStringTrait;
Expand Down Expand Up @@ -30,14 +30,33 @@ pub struct MutableLineStringArray<O: OffsetSizeTrait> {
impl<O: OffsetSizeTrait> MutableLineStringArray<O> {
/// Creates a new empty [`MutableLineStringArray`].
pub fn new() -> Self {
Self::with_capacities(0, 0)
Self::new_with_options(Default::default())
}

pub fn new_with_options(coord_type: CoordType) -> Self {
Self::with_capacities_and_options(0, 0, coord_type)
}

/// Creates a new [`MutableLineStringArray`] with a capacity.
pub fn with_capacities(coord_capacity: usize, geom_capacity: usize) -> Self {
let coords = MutableInterleavedCoordBuffer::with_capacity(coord_capacity);
Self::with_capacities_and_options(coord_capacity, geom_capacity, Default::default())
}

pub fn with_capacities_and_options(
coord_capacity: usize,
geom_capacity: usize,
coord_type: CoordType,
) -> Self {
let coords = match coord_type {
CoordType::Interleaved => MutableCoordBuffer::Interleaved(
MutableInterleavedCoordBuffer::with_capacity(coord_capacity),
),
CoordType::Separated => MutableCoordBuffer::Separated(
MutableSeparatedCoordBuffer::with_capacity(coord_capacity),
),
};
Self {
coords: MutableCoordBuffer::Interleaved(coords),
coords,
geom_offsets: OffsetsBuilder::with_capacity(geom_capacity),
validity: NullBufferBuilder::new(geom_capacity),
}
Expand Down Expand Up @@ -155,6 +174,32 @@ impl<O: OffsetSizeTrait> MutableLineStringArray<O> {
pub fn into_array_ref(self) -> Arc<dyn Array> {
Arc::new(self.into_arrow())
}

pub fn from_line_strings(
geoms: &[impl LineStringTrait<T = f64>],
coord_type: CoordType,
) -> Self {
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(Some));
second_pass(
geoms.iter().map(Some),
coord_capacity,
geom_capacity,
coord_type,
)
}

pub fn from_nullable_line_strings(
geoms: &[Option<impl LineStringTrait<T = f64>>],
coord_type: CoordType,
) -> Self {
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(|x| x.as_ref()));
second_pass(
geoms.iter().map(|x| x.as_ref()),
coord_capacity,
geom_capacity,
coord_type,
)
}
}

impl<O: OffsetSizeTrait> IntoArrow for MutableLineStringArray<O> {
Expand Down Expand Up @@ -186,11 +231,10 @@ impl<O: OffsetSizeTrait> From<MutableLineStringArray<O>> for GenericListArray<O>
}

pub(crate) fn first_pass<'a>(
geoms: impl Iterator<Item = Option<&'a (impl LineStringTrait + 'a)>>,
geoms_length: usize,
geoms: impl ExactSizeIterator + Iterator<Item = Option<&'a (impl LineStringTrait + 'a)>>,
) -> (usize, usize) {
let mut coord_capacity = 0;
let geom_capacity = geoms_length;
let geom_capacity = geoms.len();

for line_string in geoms.into_iter().flatten() {
coord_capacity += line_string.num_coords();
Expand All @@ -203,8 +247,13 @@ pub(crate) fn second_pass<'a, O: OffsetSizeTrait>(
geoms: impl Iterator<Item = Option<&'a (impl LineStringTrait<T = f64> + 'a)>>,
coord_capacity: usize,
geom_capacity: usize,
coord_type: CoordType,
) -> MutableLineStringArray<O> {
let mut array = MutableLineStringArray::with_capacities(coord_capacity, geom_capacity);
let mut array = MutableLineStringArray::with_capacities_and_options(
coord_capacity,
geom_capacity,
coord_type,
);

geoms
.into_iter()
Expand All @@ -216,22 +265,26 @@ pub(crate) fn second_pass<'a, O: OffsetSizeTrait>(

impl<O: OffsetSizeTrait, G: LineStringTrait<T = f64>> From<Vec<G>> for MutableLineStringArray<O> {
fn from(geoms: Vec<G>) -> Self {
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(Some), geoms.len());
second_pass(geoms.iter().map(Some), coord_capacity, geom_capacity)
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(Some));
second_pass(
geoms.iter().map(Some),
coord_capacity,
geom_capacity,
Default::default(),
)
}
}

impl<O: OffsetSizeTrait, G: LineStringTrait<T = f64>> From<Vec<Option<G>>>
for MutableLineStringArray<O>
{
fn from(geoms: Vec<Option<G>>) -> Self {
let geoms_len = geoms.len();
let (coord_capacity, geom_capacity) =
first_pass(geoms.iter().map(|x| x.as_ref()), geoms_len);
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(|x| x.as_ref()));
second_pass(
geoms.iter().map(|x| x.as_ref()),
coord_capacity,
geom_capacity,
Default::default(),
)
}
}
Expand All @@ -240,21 +293,26 @@ impl<O: OffsetSizeTrait, G: LineStringTrait<T = f64>> From<bumpalo::collections:
for MutableLineStringArray<O>
{
fn from(geoms: bumpalo::collections::Vec<'_, G>) -> Self {
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(Some), geoms.len());
second_pass(geoms.iter().map(Some), coord_capacity, geom_capacity)
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(Some));
second_pass(
geoms.iter().map(Some),
coord_capacity,
geom_capacity,
Default::default(),
)
}
}

impl<O: OffsetSizeTrait, G: LineStringTrait<T = f64>> From<bumpalo::collections::Vec<'_, Option<G>>>
for MutableLineStringArray<O>
{
fn from(geoms: bumpalo::collections::Vec<'_, Option<G>>) -> Self {
let (coord_capacity, geom_capacity) =
first_pass(geoms.iter().map(|x| x.as_ref()), geoms.len());
let (coord_capacity, geom_capacity) = first_pass(geoms.iter().map(|x| x.as_ref()));
second_pass(
geoms.iter().map(|x| x.as_ref()),
coord_capacity,
geom_capacity,
Default::default(),
)
}
}
Expand Down
89 changes: 55 additions & 34 deletions src/array/point/mutable.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::sync::Arc;

// use super::array::check;
use crate::array::{MutableCoordBuffer, MutableInterleavedCoordBuffer, PointArray, WKBArray};
use crate::array::{
CoordType, MutableCoordBuffer, MutableInterleavedCoordBuffer, MutableSeparatedCoordBuffer,
PointArray, WKBArray,
};
use crate::error::GeoArrowError;
use crate::geo_traits::PointTrait;
use crate::io::wkb::reader::point::WKBPoint;
Expand All @@ -21,14 +24,30 @@ pub struct MutablePointArray {
impl MutablePointArray {
/// Creates a new empty [`MutablePointArray`].
pub fn new() -> Self {
Self::with_capacity(0)
Self::new_with_options(Default::default())
}

pub fn new_with_options(coord_type: CoordType) -> Self {
Self::with_capacity_and_options(0, coord_type)
}

/// Creates a new [`MutablePointArray`] with a capacity.
pub fn with_capacity(capacity: usize) -> Self {
let coords = MutableInterleavedCoordBuffer::with_capacity(capacity);
Self::with_capacity_and_options(capacity, Default::default())
}

/// Creates a new [`MutablePointArray`] with a capacity.
pub fn with_capacity_and_options(capacity: usize, coord_type: CoordType) -> Self {
let coords = match coord_type {
CoordType::Interleaved => MutableCoordBuffer::Interleaved(
MutableInterleavedCoordBuffer::with_capacity(capacity),
),
CoordType::Separated => {
MutableCoordBuffer::Separated(MutableSeparatedCoordBuffer::with_capacity(capacity))
}
};
Self {
coords: MutableCoordBuffer::Interleaved(coords),
coords,
validity: NullBufferBuilder::new(capacity),
}
}
Expand Down Expand Up @@ -107,6 +126,28 @@ impl MutablePointArray {
self.coords.push_xy(0., 0.);
self.validity.append(false);
}

pub fn from_points<'a>(
geoms: impl ExactSizeIterator + Iterator<Item = &'a (impl PointTrait<T = f64> + 'a)>,
coord_type: CoordType,
) -> Self {
let mut mutable_array = Self::with_capacity_and_options(geoms.len(), coord_type);
geoms
.into_iter()
.for_each(|maybe_point| mutable_array.push_point(Some(maybe_point)));
mutable_array
}

pub fn from_nullable_points<'a>(
geoms: impl ExactSizeIterator + Iterator<Item = Option<&'a (impl PointTrait<T = f64> + 'a)>>,
coord_type: CoordType,
) -> MutablePointArray {
let mut mutable_array = Self::with_capacity_and_options(geoms.len(), coord_type);
geoms
.into_iter()
.for_each(|maybe_point| mutable_array.push_point(maybe_point));
mutable_array
}
}

impl MutableGeometryArray for MutablePointArray {
Expand Down Expand Up @@ -159,53 +200,33 @@ impl From<MutablePointArray> for Arc<dyn Array> {
}
}

fn from_coords<'a>(
geoms: impl Iterator<Item = &'a (impl PointTrait<T = f64> + 'a)>,
geoms_length: usize,
) -> MutablePointArray {
let mut mutable_array = MutablePointArray::with_capacity(geoms_length);
geoms
.into_iter()
.for_each(|maybe_point| mutable_array.push_point(Some(maybe_point)));
mutable_array
}

pub(crate) fn from_nullable_coords<'a>(
geoms: impl Iterator<Item = Option<&'a (impl PointTrait<T = f64> + 'a)>>,
geoms_length: usize,
) -> MutablePointArray {
let mut mutable_array = MutablePointArray::with_capacity(geoms_length);
geoms
.into_iter()
.for_each(|maybe_point| mutable_array.push_point(maybe_point));
mutable_array
}

impl<G: PointTrait<T = f64>> From<Vec<G>> for MutablePointArray {
fn from(value: Vec<G>) -> Self {
let geoms_length = value.len();
from_coords(value.iter(), geoms_length)
MutablePointArray::from_points(value.iter(), Default::default())
}
}

impl<G: PointTrait<T = f64>> From<Vec<Option<G>>> for MutablePointArray {
fn from(geoms: Vec<Option<G>>) -> Self {
let geoms_length = geoms.len();
from_nullable_coords(geoms.iter().map(|x| x.as_ref()), geoms_length)
MutablePointArray::from_nullable_points(
geoms.iter().map(|x| x.as_ref()),
Default::default(),
)
}
}

impl<G: PointTrait<T = f64>> From<bumpalo::collections::Vec<'_, G>> for MutablePointArray {
fn from(geoms: bumpalo::collections::Vec<'_, G>) -> Self {
let geoms_length = geoms.len();
from_coords(geoms.iter(), geoms_length)
MutablePointArray::from_points(geoms.iter(), Default::default())
}
}

impl<G: PointTrait<T = f64>> From<bumpalo::collections::Vec<'_, Option<G>>> for MutablePointArray {
fn from(geoms: bumpalo::collections::Vec<'_, Option<G>>) -> Self {
let geoms_length = geoms.len();
from_nullable_coords(geoms.iter().map(|x| x.as_ref()), geoms_length)
MutablePointArray::from_nullable_points(
geoms.iter().map(|x| x.as_ref()),
Default::default(),
)
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/io/geos/array/point.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::array::point::mutable::from_nullable_coords;
use crate::array::{MutablePointArray, PointArray};
use crate::error::GeoArrowError;
use crate::io::geos::scalar::GEOSPoint;
Expand All @@ -7,15 +6,14 @@ impl<'a> TryFrom<Vec<Option<geos::Geometry<'a>>>> for MutablePointArray {
type Error = GeoArrowError;

fn try_from(value: Vec<Option<geos::Geometry<'a>>>) -> std::result::Result<Self, Self::Error> {
let length = value.len();
// TODO: don't use new_unchecked
let geos_linestring_objects: Vec<Option<GEOSPoint>> = value
.into_iter()
.map(|geom| geom.map(GEOSPoint::new_unchecked))
.collect();
Ok(from_nullable_coords(
Ok(MutablePointArray::from_nullable_points(
geos_linestring_objects.iter().map(|item| item.as_ref()),
length,
Default::default(),
))
}
}
Expand Down

0 comments on commit f4830fd

Please sign in to comment.