use std::any::Any;
use std::fmt;
use std::mem;
use crate::array::{Array, ArrayData, ArrayDataRef};
use crate::datatypes::*;
pub struct NullArray {
data: ArrayDataRef,
}
impl NullArray {
pub fn new(length: usize) -> Self {
let array_data = ArrayData::builder(DataType::Null).len(length).build();
NullArray::from(array_data)
}
}
impl Array for NullArray {
fn as_any(&self) -> &Any {
self
}
fn data(&self) -> ArrayDataRef {
self.data.clone()
}
fn data_ref(&self) -> &ArrayDataRef {
&self.data
}
fn is_null(&self, _index: usize) -> bool {
true
}
fn is_valid(&self, _index: usize) -> bool {
false
}
fn null_count(&self) -> usize {
self.data_ref().len()
}
fn get_buffer_memory_size(&self) -> usize {
self.data.get_buffer_memory_size()
}
fn get_array_memory_size(&self) -> usize {
self.data.get_array_memory_size() + mem::size_of_val(self)
}
}
impl From<ArrayDataRef> for NullArray {
fn from(data: ArrayDataRef) -> Self {
assert_eq!(
data.buffers().len(),
0,
"NullArray data should contain 0 buffers"
);
assert!(
data.null_buffer().is_none(),
"NullArray data should not contain a null buffer, as no buffers are required"
);
Self { data }
}
}
impl fmt::Debug for NullArray {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "NullArray({})", self.len())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_null_array() {
let null_arr = NullArray::new(32);
assert_eq!(null_arr.len(), 32);
assert_eq!(null_arr.null_count(), 32);
assert_eq!(null_arr.is_valid(0), false);
assert_eq!(0, null_arr.get_buffer_memory_size());
let internals_of_null_array = 64; assert_eq!(
null_arr.get_buffer_memory_size() + internals_of_null_array,
null_arr.get_array_memory_size()
);
}
#[test]
fn test_null_array_slice() {
let array1 = NullArray::new(32);
let array2 = array1.slice(8, 16);
assert_eq!(array2.len(), 16);
assert_eq!(array2.null_count(), 16);
assert_eq!(array2.offset(), 8);
}
#[test]
fn test_debug_null_array() {
let array = NullArray::new(1024 * 1024);
assert_eq!(format!("{:?}", array), "NullArray(1048576)");
}
}