use arrow_array::builder::make_view;
use arrow_buffer::Buffer;
use vortex_array::array::{PrimitiveArray, VarBinArray, VarBinViewArray};
use vortex_array::{Array, ArrayDType, Canonical, IntoArray, IntoCanonical};
use vortex_error::VortexResult;
use crate::FSSTArray;
impl IntoCanonical for FSSTArray {
fn into_canonical(self) -> VortexResult<Canonical> {
self.with_decompressor(|decompressor| {
let compressed_bytes = VarBinArray::try_from(self.codes())?
.sliced_bytes()?
.as_primitive();
let uncompressed_bytes =
decompressor.decompress(compressed_bytes.maybe_null_slice::<u8>());
let uncompressed_lens_array = self
.uncompressed_lengths()
.into_canonical()?
.into_primitive()?;
let uncompressed_lens_slice = uncompressed_lens_array.maybe_null_slice::<i32>();
let views: Vec<u128> = uncompressed_lens_slice
.iter()
.scan(0, |offset, len| {
let str_start = *offset;
let str_end = *offset + len;
*offset += len;
Some(make_view(
&uncompressed_bytes[(str_start as usize)..(str_end as usize)],
0u32,
str_start as u32,
))
})
.collect();
let views_array: Array = Buffer::from(views).into();
let uncompressed_bytes_array = PrimitiveArray::from(uncompressed_bytes).into_array();
VarBinViewArray::try_new(
views_array,
vec![uncompressed_bytes_array],
self.dtype().clone(),
self.validity(),
)
.map(Canonical::VarBinView)
})
}
}