reifydb_value/value/container/
fixed_array.rs1use arrow_array::{Array, FixedSizeBinaryArray};
5use arrow_buffer::{MutableBuffer, NullBuffer};
6use arrow_select::filter::FilterPredicate;
7
8use crate::{
9 Result,
10 util::{bitmap, kernel},
11};
12
13pub fn assert_whole_rows(width: usize, bytes: usize) {
14 assert_eq!(
15 bytes % width,
16 0,
17 "fixed size binary buffer of {bytes} bytes is not a whole number of {width} byte rows"
18 );
19}
20
21pub fn from_buffer(width: usize, buffer: MutableBuffer) -> FixedSizeBinaryArray {
22 assert_whole_rows(width, buffer.len());
23 FixedSizeBinaryArray::new(width as i32, buffer.into(), None)
24}
25
26pub fn slice(array: &FixedSizeBinaryArray, start: usize, end: usize) -> FixedSizeBinaryArray {
27 let end = end.min(array.len());
28 let start = start.min(end);
29 array.slice(start, end - start)
30}
31
32pub fn take(array: &FixedSizeBinaryArray, num: usize) -> FixedSizeBinaryArray {
33 slice(array, 0, num)
34}
35
36pub fn filter_with(array: &FixedSizeBinaryArray, predicate: &FilterPredicate) -> FixedSizeBinaryArray {
37 let selected = kernel::filtered(array, predicate);
38 let nulls = kernel::kept_nulls(array, &selected);
39 attach_nulls(selected, nulls)
40}
41
42pub fn reorder(array: &FixedSizeBinaryArray, indices: &[usize]) -> Result<FixedSizeBinaryArray> {
43 let width = array.value_length() as usize;
44 kernel::rows_in_range(indices, array.len())?;
45 let bytes = &array.value_data()[..array.len() * width];
46 let mut reordered = MutableBuffer::with_capacity(indices.len() * width);
47 for &idx in indices {
48 reordered.extend_from_slice(&bytes[idx * width..(idx + 1) * width]);
49 }
50 Ok(attach_nulls(from_buffer(width, reordered), bitmap::reorder_nulls(array.logical_nulls().as_ref(), indices)))
51}
52
53pub fn attach_nulls(array: FixedSizeBinaryArray, nulls: Option<NullBuffer>) -> FixedSizeBinaryArray {
54 bitmap::assert_nulls_len(nulls.as_ref(), array.len());
55 let (width, values, _) = array.into_parts();
56 FixedSizeBinaryArray::new(width, values, nulls)
57}
58
59pub fn capacity(array: &FixedSizeBinaryArray) -> usize {
60 let buffer = array.values();
61 if buffer.strong_count() == 1 {
62 buffer.capacity() / array.value_length() as usize
63 } else {
64 array.len()
65 }
66}
67
68pub fn heap_size(array: &FixedSizeBinaryArray) -> usize {
69 capacity(array) * array.value_length() as usize
70}