Skip to content

Commit

Permalink
Add an arrow1-interfacr on top of Loggable
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Nov 21, 2024
1 parent 4a431a3 commit 8c66f64
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6342,6 +6342,7 @@ name = "re_types_core"
version = "0.21.0-alpha.1+dev"
dependencies = [
"anyhow",
"arrow",
"backtrace",
"bytemuck",
"criterion",
Expand Down
2 changes: 2 additions & 0 deletions crates/store/re_types_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ re_tuid.workspace = true

# External
anyhow.workspace = true
arrow.workspace = true
arrow2 = { workspace = true, features = [
"arrow",
"io_ipc",
"io_print",
"compute_concatenate",
Expand Down
64 changes: 60 additions & 4 deletions crates/store/re_types_core/src/loggable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ use crate::{Archetype, ComponentBatch, LoggableBatch};
/// Implementing the [`Loggable`] trait automatically derives the [`LoggableBatch`] implementation,
/// which makes it possible to work with lists' worth of data in a generic fashion.
pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes {
/// The underlying [`arrow::datatypes::DataType`], excluding datatype extensions.
fn arrow_datatype() -> arrow::datatypes::DataType {
Self::arrow2_datatype().into()
}

/// The underlying [`arrow2::datatypes::DataType`], excluding datatype extensions.
fn arrow2_datatype() -> arrow2::datatypes::DataType;

Expand All @@ -25,9 +30,24 @@ pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes {
/// When using Rerun's builtin components & datatypes, this can only fail if the data
/// exceeds the maximum number of entries in an Arrow array (2^31 for standard arrays,
/// 2^63 for large arrays).
fn to_arrow_opt<'a>(
data: impl IntoIterator<Item = Option<impl Into<std::borrow::Cow<'a, Self>>>>,
) -> SerializationResult<arrow::array::ArrayData>
where
Self: 'a,
{
Self::to_arrow2_opt(data).map(|array| arrow2::array::to_data(array.as_ref()))
}

/// Given an iterator of options of owned or reference values to the current
/// [`Loggable`], serializes them into an Arrow2 array.
///
/// When using Rerun's builtin components & datatypes, this can only fail if the data
/// exceeds the maximum number of entries in an Arrow2 array (2^31 for standard arrays,
/// 2^63 for large arrays).
fn to_arrow2_opt<'a>(
data: impl IntoIterator<Item = Option<impl Into<std::borrow::Cow<'a, Self>>>>,
) -> SerializationResult<Box<dyn ::arrow2::array::Array>>
) -> SerializationResult<Box<dyn arrow2::array::Array>>
where
Self: 'a;

Expand All @@ -40,9 +60,26 @@ pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes {
/// exceeds the maximum number of entries in an Arrow array (2^31 for standard arrays,
/// 2^63 for large arrays).
#[inline]
fn to_arrow<'a>(
data: impl IntoIterator<Item = impl Into<std::borrow::Cow<'a, Self>>>,
) -> SerializationResult<arrow::array::ArrayData>
where
Self: 'a,
{
re_tracing::profile_function!();
Self::to_arrow_opt(data.into_iter().map(Some))
}

/// Given an iterator of owned or reference values to the current [`Loggable`], serializes
/// them into an Arrow2 array.
///
/// When using Rerun's builtin components & datatypes, this can only fail if the data
/// exceeds the maximum number of entries in an Arrow2 array (2^31 for standard arrays,
/// 2^63 for large arrays).
#[inline]
fn to_arrow2<'a>(
data: impl IntoIterator<Item = impl Into<std::borrow::Cow<'a, Self>>>,
) -> SerializationResult<Box<dyn ::arrow2::array::Array>>
) -> SerializationResult<Box<dyn arrow2::array::Array>>
where
Self: 'a,
{
Expand All @@ -54,7 +91,21 @@ pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes {

/// Given an Arrow array, deserializes it into a collection of [`Loggable`]s.
#[inline]
fn from_arrow2(data: &dyn ::arrow2::array::Array) -> DeserializationResult<Vec<Self>> {
fn from_arrow(data: &arrow::array::ArrayData) -> DeserializationResult<Vec<Self>> {
re_tracing::profile_function!();
Self::from_arrow_opt(data)?
.into_iter()
.map(|opt| {
opt.ok_or_else(|| crate::DeserializationError::MissingData {
backtrace: _Backtrace::new_unresolved(),
})
})
.collect::<DeserializationResult<Vec<_>>>()
}

/// Given an Arrow2 array, deserializes it into a collection of [`Loggable`]s.
#[inline]
fn from_arrow2(data: &dyn arrow2::array::Array) -> DeserializationResult<Vec<Self>> {
re_tracing::profile_function!();
Self::from_arrow2_opt(data)?
.into_iter()
Expand All @@ -67,8 +118,13 @@ pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes {
}

/// Given an Arrow array, deserializes it into a collection of optional [`Loggable`]s.
fn from_arrow_opt(data: &arrow::array::ArrayData) -> DeserializationResult<Vec<Option<Self>>> {
Self::from_arrow2_opt(arrow2::array::from_data(data).as_ref())
}

/// Given an Arrow2 array, deserializes it into a collection of optional [`Loggable`]s.
fn from_arrow2_opt(
data: &dyn ::arrow2::array::Array,
data: &dyn arrow2::array::Array,
) -> DeserializationResult<Vec<Option<Self>>> {
_ = data; // NOTE: do this here to avoid breaking users' autocomplete snippets
Err(crate::DeserializationError::NotImplemented {
Expand Down

0 comments on commit 8c66f64

Please sign in to comment.