Skip to main content

reifydb_value/value/container/
fixed_array.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use 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}