datatypes/vectors/
validity.rsuse arrow::array::ArrayData;
use arrow::buffer::NullBuffer;
#[derive(Debug, PartialEq)]
enum ValidityKind {
Slots {
bitmap: NullBuffer,
len: usize,
null_count: usize,
},
AllValid { len: usize },
AllNull { len: usize },
}
#[derive(Debug, PartialEq)]
pub struct Validity {
kind: ValidityKind,
}
impl Validity {
pub fn from_array_data(data: ArrayData) -> Validity {
match data.nulls() {
Some(null_buf) => Validity {
kind: ValidityKind::Slots {
bitmap: null_buf.clone(),
len: data.len(),
null_count: data.null_count(),
},
},
None => Validity::all_valid(data.len()),
}
}
pub fn all_valid(len: usize) -> Validity {
Validity {
kind: ValidityKind::AllValid { len },
}
}
pub fn all_null(len: usize) -> Validity {
Validity {
kind: ValidityKind::AllNull { len },
}
}
pub fn is_set(&self, i: usize) -> bool {
match &self.kind {
ValidityKind::Slots { bitmap, .. } => bitmap.is_valid(i),
ValidityKind::AllValid { len } => i < *len,
ValidityKind::AllNull { .. } => false,
}
}
pub fn is_all_null(&self) -> bool {
match self.kind {
ValidityKind::Slots {
len, null_count, ..
} => len == null_count,
ValidityKind::AllValid { .. } => false,
ValidityKind::AllNull { .. } => true,
}
}
pub fn is_all_valid(&self) -> bool {
match self.kind {
ValidityKind::Slots { null_count, .. } => null_count == 0,
ValidityKind::AllValid { .. } => true,
ValidityKind::AllNull { .. } => false,
}
}
pub fn null_count(&self) -> usize {
match self.kind {
ValidityKind::Slots { null_count, .. } => null_count,
ValidityKind::AllValid { .. } => 0,
ValidityKind::AllNull { len } => len,
}
}
}
#[cfg(test)]
mod tests {
use arrow::array::{Array, Int32Array};
use super::*;
#[test]
fn test_all_valid() {
let validity = Validity::all_valid(5);
assert!(validity.is_all_valid());
assert!(!validity.is_all_null());
assert_eq!(0, validity.null_count());
for i in 0..5 {
assert!(validity.is_set(i));
}
assert!(!validity.is_set(5));
}
#[test]
fn test_all_null() {
let validity = Validity::all_null(5);
assert!(validity.is_all_null());
assert!(!validity.is_all_valid());
assert_eq!(5, validity.null_count());
for i in 0..5 {
assert!(!validity.is_set(i));
}
assert!(!validity.is_set(5));
}
#[test]
fn test_from_array_data() {
let array = Int32Array::from_iter([None, Some(1), None]);
let validity = Validity::from_array_data(array.to_data());
assert_eq!(2, validity.null_count());
assert!(!validity.is_set(0));
assert!(validity.is_set(1));
assert!(!validity.is_set(2));
assert!(!validity.is_all_null());
assert!(!validity.is_all_valid());
let array = Int32Array::from_iter([None, None]);
let validity = Validity::from_array_data(array.to_data());
assert!(validity.is_all_null());
assert!(!validity.is_all_valid());
assert_eq!(2, validity.null_count());
let array = Int32Array::from_iter_values([1, 2]);
let validity = Validity::from_array_data(array.to_data());
assert!(!validity.is_all_null());
assert!(validity.is_all_valid());
assert_eq!(0, validity.null_count());
}
}