arrow2/array/fixed_size_binary/
mod.rs1use crate::{bitmap::Bitmap, buffer::Buffer, datatypes::DataType, error::Error};
2
3use super::Array;
4
5#[cfg(feature = "arrow")]
6mod data;
7mod ffi;
8pub(super) mod fmt;
9mod iterator;
10mod mutable;
11pub use mutable::*;
12
13#[derive(Clone)]
16pub struct FixedSizeBinaryArray {
17 size: usize, data_type: DataType,
19 values: Buffer<u8>,
20 validity: Option<Bitmap>,
21}
22
23impl FixedSizeBinaryArray {
24 pub fn try_new(
32 data_type: DataType,
33 values: Buffer<u8>,
34 validity: Option<Bitmap>,
35 ) -> Result<Self, Error> {
36 let size = Self::maybe_get_size(&data_type)?;
37
38 if values.len() % size != 0 {
39 return Err(Error::oos(format!(
40 "values (of len {}) must be a multiple of size ({}) in FixedSizeBinaryArray.",
41 values.len(),
42 size
43 )));
44 }
45 let len = values.len() / size;
46
47 if validity
48 .as_ref()
49 .map_or(false, |validity| validity.len() != len)
50 {
51 return Err(Error::oos(
52 "validity mask length must be equal to the number of values divided by size",
53 ));
54 }
55
56 Ok(Self {
57 size,
58 data_type,
59 values,
60 validity,
61 })
62 }
63
64 pub fn new(data_type: DataType, values: Buffer<u8>, validity: Option<Bitmap>) -> Self {
71 Self::try_new(data_type, values, validity).unwrap()
72 }
73
74 pub fn new_empty(data_type: DataType) -> Self {
76 Self::new(data_type, Buffer::new(), None)
77 }
78
79 pub fn new_null(data_type: DataType, length: usize) -> Self {
81 let size = Self::maybe_get_size(&data_type).unwrap();
82 Self::new(
83 data_type,
84 vec![0u8; length * size].into(),
85 Some(Bitmap::new_zeroed(length)),
86 )
87 }
88}
89
90impl FixedSizeBinaryArray {
92 pub fn slice(&mut self, offset: usize, length: usize) {
98 assert!(
99 offset + length <= self.len(),
100 "the offset of the new Buffer cannot exceed the existing length"
101 );
102 unsafe { self.slice_unchecked(offset, length) }
103 }
104
105 pub unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
111 self.validity.as_mut().and_then(|bitmap| {
112 bitmap.slice_unchecked(offset, length);
113 (bitmap.unset_bits() > 0).then(|| bitmap)
114 });
115 self.values
116 .slice_unchecked(offset * self.size, length * self.size);
117 }
118
119 impl_sliced!();
120 impl_mut_validity!();
121 impl_into_array!();
122}
123
124impl FixedSizeBinaryArray {
126 #[inline]
128 pub fn len(&self) -> usize {
129 self.values.len() / self.size
130 }
131
132 #[inline]
134 pub fn validity(&self) -> Option<&Bitmap> {
135 self.validity.as_ref()
136 }
137
138 pub fn values(&self) -> &Buffer<u8> {
140 &self.values
141 }
142
143 #[inline]
147 pub fn value(&self, i: usize) -> &[u8] {
148 assert!(i < self.len());
149 unsafe { self.value_unchecked(i) }
150 }
151
152 #[inline]
156 pub unsafe fn value_unchecked(&self, i: usize) -> &[u8] {
157 self.values
159 .get_unchecked(i * self.size..(i + 1) * self.size)
160 }
161
162 #[inline]
166 pub fn get(&self, i: usize) -> Option<&[u8]> {
167 if !self.is_null(i) {
168 unsafe { Some(self.value_unchecked(i)) }
170 } else {
171 None
172 }
173 }
174
175 #[inline]
180 pub fn to(self, data_type: DataType) -> Self {
181 match (
182 data_type.to_logical_type(),
183 self.data_type().to_logical_type(),
184 ) {
185 (DataType::FixedSizeBinary(size_a), DataType::FixedSizeBinary(size_b))
186 if size_a == size_b => {}
187 _ => panic!("Wrong DataType"),
188 }
189
190 Self {
191 size: self.size,
192 data_type,
193 values: self.values,
194 validity: self.validity,
195 }
196 }
197
198 pub fn size(&self) -> usize {
200 self.size
201 }
202}
203
204impl FixedSizeBinaryArray {
205 pub(crate) fn maybe_get_size(data_type: &DataType) -> Result<usize, Error> {
206 match data_type.to_logical_type() {
207 DataType::FixedSizeBinary(size) => {
208 if *size == 0 {
209 return Err(Error::oos("FixedSizeBinaryArray expects a positive size"));
210 }
211 Ok(*size)
212 }
213 _ => Err(Error::oos(
214 "FixedSizeBinaryArray expects DataType::FixedSizeBinary",
215 )),
216 }
217 }
218
219 pub(crate) fn get_size(data_type: &DataType) -> usize {
220 Self::maybe_get_size(data_type).unwrap()
221 }
222}
223
224impl Array for FixedSizeBinaryArray {
225 impl_common_array!();
226
227 fn validity(&self) -> Option<&Bitmap> {
228 self.validity.as_ref()
229 }
230
231 #[inline]
232 fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
233 Box::new(self.clone().with_validity(validity))
234 }
235}
236
237impl FixedSizeBinaryArray {
238 pub fn try_from_iter<P: AsRef<[u8]>, I: IntoIterator<Item = Option<P>>>(
240 iter: I,
241 size: usize,
242 ) -> Result<Self, Error> {
243 MutableFixedSizeBinaryArray::try_from_iter(iter, size).map(|x| x.into())
244 }
245
246 pub fn from_iter<P: AsRef<[u8]>, I: IntoIterator<Item = Option<P>>>(
248 iter: I,
249 size: usize,
250 ) -> Self {
251 MutableFixedSizeBinaryArray::try_from_iter(iter, size)
252 .unwrap()
253 .into()
254 }
255
256 pub fn from_slice<const N: usize, P: AsRef<[[u8; N]]>>(a: P) -> Self {
258 let values = a.as_ref().iter().flatten().copied().collect::<Vec<_>>();
259 Self::new(DataType::FixedSizeBinary(N), values.into(), None)
260 }
261
262 pub fn from<const N: usize, P: AsRef<[Option<[u8; N]>]>>(slice: P) -> Self {
265 MutableFixedSizeBinaryArray::from(slice).into()
266 }
267}
268
269pub trait FixedSizeBinaryValues {
270 fn values(&self) -> &[u8];
271 fn size(&self) -> usize;
272}
273
274impl FixedSizeBinaryValues for FixedSizeBinaryArray {
275 #[inline]
276 fn values(&self) -> &[u8] {
277 &self.values
278 }
279
280 #[inline]
281 fn size(&self) -> usize {
282 self.size
283 }
284}