Skip to content

Commit

Permalink
Support construct BooleanArray from &[u8]
Browse files Browse the repository at this point in the history
  • Loading branch information
chloro-pn committed Jul 25, 2024
1 parent 613e93e commit 0420332
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
42 changes: 42 additions & 0 deletions arrow-array/src/array/boolean_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ use std::sync::Arc;
/// assert_eq!(&values, &[Some(true), None, Some(false), None, Some(false)])
/// ```
///
/// # Example: From &[u8]
///
/// ```
/// # use arrow_array::{Array, BooleanArray};
/// let v: Vec<u8> = vec![1];
/// let slice = &v[..];
/// let arr = BooleanArray::from(slice);
/// assert_eq!(8, arr.len());
/// assert!(!arr.is_null(0));
/// assert!(arr.value(0));
/// ```
/// convert each bit in `&[u8]` to boolean and use it to build [`BooleanArray`].
/// using this method will make the following two points self-evident:
/// * There is no `null` in the constructed [`BooleanArray`]
/// * The length of the constructed [`BooleanArray`] is always a multiple of 8;
///
/// # Example: Using Builder
///
/// ```
Expand Down Expand Up @@ -349,6 +365,12 @@ impl From<Vec<Option<bool>>> for BooleanArray {
}
}

impl From<&[u8]> for BooleanArray {
fn from(value: &[u8]) -> Self {
Self::from(BooleanBuffer::from(value))
}
}

impl From<ArrayData> for BooleanArray {
fn from(data: ArrayData) -> Self {
assert_eq!(
Expand Down Expand Up @@ -509,6 +531,26 @@ mod tests {
}
}

#[test]
fn test_boolean_array_from_slice_u8() {
let v: Vec<u8> = vec![1, 2, 3];
let slice = &v[..];
let arr = BooleanArray::from(slice);
assert_eq!(24, arr.len());
assert_eq!(0, arr.offset());
assert_eq!(0, arr.null_count());
assert!(arr.nulls().is_none());
for i in 0..24 {
assert!(!arr.is_null(i));
assert!(arr.is_valid(i));
assert_eq!(
i == 0 || i == 9 || i == 16 || i == 17,
arr.value(i),
"failed t {i}"
)
}
}

#[test]
fn test_boolean_array_from_iter() {
let v = vec![Some(false), Some(true), Some(false), Some(true)];
Expand Down
30 changes: 30 additions & 0 deletions arrow-buffer/src/buffer/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
bit_util, buffer_bin_and, buffer_bin_or, buffer_bin_xor, buffer_unary_not,
BooleanBufferBuilder, Buffer, MutableBuffer,
};

use std::ops::{BitAnd, BitOr, BitXor, Not};

/// A slice-able [`Buffer`] containing bit-packed booleans
Expand Down Expand Up @@ -274,6 +275,12 @@ impl From<&[bool]> for BooleanBuffer {
}
}

impl From<&[u8]> for BooleanBuffer {
fn from(slice: &[u8]) -> Self {
BooleanBuffer::new(Buffer::from(slice), 0, slice.len() * 8)
}
}

impl From<Vec<bool>> for BooleanBuffer {
fn from(value: Vec<bool>) -> Self {
value.as_slice().into()
Expand Down Expand Up @@ -414,4 +421,27 @@ mod tests {
let expected = BooleanBuffer::new(Buffer::from(&[255, 254, 254, 255, 255]), offset, len);
assert_eq!(!boolean_buf, expected);
}

#[test]
fn test_boolean_from_slice_bool() {
let v = [true, false, false];
let buf = BooleanBuffer::from(&v[..]);
assert_eq!(buf.offset(), 0);
assert_eq!(buf.len(), 3);
assert_eq!(buf.values().len(), 1);
assert!(buf.value(0));
}

#[test]
fn test_boolean_from_slice_u8() {
let v = [1_u8, 2, 3];
let buf = BooleanBuffer::from(&v[..]);
assert_eq!(buf.offset(), 0);
assert_eq!(buf.len(), 24);
assert_eq!(buf.values().len(), 3);
assert!(buf.value(0));
assert!(buf.value(9));
assert!(buf.value(16));
assert!(buf.value(17));
}
}

0 comments on commit 0420332

Please sign in to comment.