Skip to content

Commit

Permalink
Added support for JSON ser/de records layout (jorgecarleitao#1275)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnIrishDuck authored and ritchie46 committed Nov 6, 2022
1 parent fa90592 commit 396db63
Show file tree
Hide file tree
Showing 11 changed files with 850 additions and 38 deletions.
5 changes: 5 additions & 0 deletions src/array/fixed_size_list/mutable.rs
Expand Up @@ -59,6 +59,11 @@ impl<M: MutableArray> MutableFixedSizeListArray<M> {
}
}

/// Returns the size (number of elements per slot) of this [`FixedSizeListArray`].
pub const fn size(&self) -> usize {
self.size
}

/// The inner values
pub fn values(&self) -> &M {
&self.values
Expand Down
78 changes: 76 additions & 2 deletions src/array/list/mutable.rs
@@ -1,10 +1,11 @@
use std::sync::Arc;

use crate::{
array::{Array, MutableArray, Offset, TryExtend, TryPush},
array::{specification::try_check_offsets, Array, MutableArray, Offset, TryExtend, TryPush},
bitmap::MutableBitmap,
datatypes::{DataType, Field},
error::{Error, Result},
trusted_len::TrustedLen,
};

use super::ListArray;
Expand Down Expand Up @@ -152,6 +153,75 @@ impl<O: Offset, M: MutableArray> MutableListArray<O, M> {
}
}

/// Expand this array, using elements from the underlying backing array.
/// Assumes the expansion begins at the highest previous offset, or zero if
/// this [MutableListArray] is currently empty.
///
/// Panics if:
/// - the new offsets are not in monotonic increasing order.
/// - any new offset is not in bounds of the backing array.
/// - the passed iterator has no upper bound.
pub(crate) fn extend_offsets<II>(&mut self, expansion: II)
where
II: TrustedLen<Item = Option<O>>,
{
let current_len = self.offsets.len();
let (_, upper) = expansion.size_hint();
let upper = upper.expect("iterator must have upper bound");
if current_len == 0 && upper > 0 {
self.offsets.push(O::zero());
}
// safety: checked below
unsafe { self.unsafe_extend_offsets(expansion) };
if self.offsets.len() > current_len {
// check all inserted offsets
try_check_offsets(&self.offsets[current_len..], self.values.len())
.expect("invalid offsets");
}
// else expansion is empty, and this is trivially safe.
}

/// Expand this array, using elements from the underlying backing array.
/// Assumes the expansion begins at the highest previous offset, or zero if
/// this [MutableListArray] is currently empty.
///
/// # Safety
///
/// Assumes that `offsets` are in order, and do not overrun the underlying
/// `values` backing array.
///
/// Also assumes the expansion begins at the highest previous offset, or
/// zero if the array is currently empty.
///
/// Panics if the passed iterator has no upper bound.
pub(crate) unsafe fn unsafe_extend_offsets<II>(&mut self, expansion: II)
where
II: TrustedLen<Item = Option<O>>,
{
let (_, upper) = expansion.size_hint();
let upper = upper.expect("iterator must have upper bound");
let final_size = self.len() + upper;
self.offsets.reserve(upper);

for item in expansion {
match item {
Some(offset) => {
self.offsets.push(offset);
if let Some(validity) = &mut self.validity {
validity.push(true);
}
}
None => self.push_null(),
}

if let Some(validity) = &mut self.validity {
if validity.capacity() < final_size {
validity.reserve(final_size - validity.capacity());
}
}
}
}

/// The values
pub fn mut_values(&mut self) -> &mut M {
&mut self.values
Expand Down Expand Up @@ -209,11 +279,15 @@ impl<O: Offset, M: MutableArray> MutableListArray<O, M> {
validity.shrink_to_fit()
}
}

fn len(&self) -> usize {
self.offsets.len() - 1
}
}

impl<O: Offset, M: MutableArray + 'static> MutableArray for MutableListArray<O, M> {
fn len(&self) -> usize {
self.offsets.len() - 1
MutableListArray::len(self)
}

fn validity(&self) -> Option<&MutableBitmap> {
Expand Down
53 changes: 53 additions & 0 deletions src/array/mod.rs
Expand Up @@ -17,6 +17,7 @@
//! Most arrays contain a [`MutableArray`] counterpart that is neither clonable nor slicable, but
//! can be operated in-place.
use std::any::Any;
use std::sync::Arc;

use crate::error::Result;
use crate::{
Expand Down Expand Up @@ -113,6 +114,15 @@ pub trait Array: Send + Sync + dyn_clone::DynClone + 'static {

dyn_clone::clone_trait_object!(Array);

/// A trait describing an array with a backing store that can be preallocated to
/// a given size.
pub(crate) trait Container {
/// Create this array with a given capacity.
fn with_capacity(capacity: usize) -> Self
where
Self: Sized;
}

/// A trait describing a mutable array; i.e. an array whose values can be changed.
/// Mutable arrays cannot be cloned but can be mutated in place,
/// thereby making them useful to perform numeric operations without allocations.
Expand Down Expand Up @@ -170,6 +180,49 @@ pub trait MutableArray: std::fmt::Debug + Send + Sync {
fn shrink_to_fit(&mut self);
}

impl MutableArray for Box<dyn MutableArray> {
fn len(&self) -> usize {
self.as_ref().len()
}

fn validity(&self) -> Option<&MutableBitmap> {
self.as_ref().validity()
}

fn as_box(&mut self) -> Box<dyn Array> {
self.as_mut().as_box()
}

fn as_arc(&mut self) -> Arc<dyn Array> {
self.as_mut().as_arc()
}

fn data_type(&self) -> &DataType {
self.as_ref().data_type()
}

fn as_any(&self) -> &dyn std::any::Any {
self.as_ref().as_any()
}

fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
self.as_mut().as_mut_any()
}

#[inline]
fn push_null(&mut self) {
self.as_mut().push_null()
}

fn shrink_to_fit(&mut self) {
self.as_mut().shrink_to_fit();
}

fn reserve(&mut self, additional: usize) {
self.as_mut().reserve(additional);
}
}

macro_rules! general_dyn {
($array:expr, $ty:ty, $f:expr) => {{
let array = $array.as_any().downcast_ref::<$ty>().unwrap();
Expand Down

0 comments on commit 396db63

Please sign in to comment.