1use crate::array::{get_offsets_from_buffer, print_long_array};
19use crate::builder::GenericByteBuilder;
20use crate::iterator::ArrayIter;
21use crate::types::ByteArrayType;
22use crate::types::bytes::ByteArrayNativeType;
23use crate::{Array, ArrayAccessor, ArrayRef, OffsetSizeTrait, Scalar};
24use arrow_buffer::{ArrowNativeType, Buffer, MutableBuffer};
25use arrow_buffer::{NullBuffer, OffsetBuffer};
26use arrow_data::{ArrayData, ArrayDataBuilder};
27use arrow_schema::{ArrowError, DataType};
28use std::any::Any;
29use std::sync::Arc;
30
31pub struct GenericByteArray<T: ByteArrayType> {
88 data_type: DataType,
89 value_offsets: OffsetBuffer<T::Offset>,
90 value_data: Buffer,
91 nulls: Option<NullBuffer>,
92}
93
94impl<T: ByteArrayType> Clone for GenericByteArray<T> {
95 fn clone(&self) -> Self {
96 Self {
97 data_type: T::DATA_TYPE,
98 value_offsets: self.value_offsets.clone(),
99 value_data: self.value_data.clone(),
100 nulls: self.nulls.clone(),
101 }
102 }
103}
104
105impl<T: ByteArrayType> GenericByteArray<T> {
106 pub const DATA_TYPE: DataType = T::DATA_TYPE;
108
109 pub fn new(
115 offsets: OffsetBuffer<T::Offset>,
116 values: Buffer,
117 nulls: Option<NullBuffer>,
118 ) -> Self {
119 Self::try_new(offsets, values, nulls).unwrap()
120 }
121
122 pub fn try_new(
129 offsets: OffsetBuffer<T::Offset>,
130 values: Buffer,
131 nulls: Option<NullBuffer>,
132 ) -> Result<Self, ArrowError> {
133 let len = offsets.len() - 1;
134
135 T::validate(&offsets, &values)?;
137
138 if let Some(n) = nulls.as_ref()
139 && n.len() != len
140 {
141 return Err(ArrowError::InvalidArgumentError(format!(
142 "Incorrect length of null buffer for {}{}Array, expected {len} got {}",
143 T::Offset::PREFIX,
144 T::PREFIX,
145 n.len(),
146 )));
147 }
148
149 Ok(Self {
150 data_type: T::DATA_TYPE,
151 value_offsets: offsets,
152 value_data: values,
153 nulls,
154 })
155 }
156
157 pub unsafe fn new_unchecked(
163 offsets: OffsetBuffer<T::Offset>,
164 values: Buffer,
165 nulls: Option<NullBuffer>,
166 ) -> Self {
167 if cfg!(feature = "force_validate") {
168 return Self::new(offsets, values, nulls);
169 }
170 Self {
171 data_type: T::DATA_TYPE,
172 value_offsets: offsets,
173 value_data: values,
174 nulls,
175 }
176 }
177
178 pub fn new_null(len: usize) -> Self {
180 Self {
181 data_type: T::DATA_TYPE,
182 value_offsets: OffsetBuffer::new_zeroed(len),
183 value_data: MutableBuffer::new(0).into(),
184 nulls: Some(NullBuffer::new_null(len)),
185 }
186 }
187
188 pub fn new_scalar(value: impl AsRef<T::Native>) -> Scalar<Self> {
190 Scalar::new(Self::from_iter_values(std::iter::once(value)))
191 }
192
193 pub fn new_repeated(value: impl AsRef<T::Native>, repeat_count: usize) -> Self {
199 let s: &[u8] = value.as_ref().as_ref();
200 let value_offsets = OffsetBuffer::from_repeated_length(s.len(), repeat_count);
201 let bytes: Buffer = {
202 let mut mutable_buffer = MutableBuffer::with_capacity(0);
203 mutable_buffer.repeat_slice_n_times(s, repeat_count);
204
205 mutable_buffer.into()
206 };
207
208 Self {
209 data_type: T::DATA_TYPE,
210 value_data: bytes,
211 value_offsets,
212 nulls: None,
213 }
214 }
215
216 pub fn from_iter_values<Ptr, I>(iter: I) -> Self
222 where
223 Ptr: AsRef<T::Native>,
224 I: IntoIterator<Item = Ptr>,
225 {
226 let iter = iter.into_iter();
227 let (_, data_len) = iter.size_hint();
228 let data_len = data_len.expect("Iterator must be sized"); let mut offsets = MutableBuffer::new((data_len + 1) * std::mem::size_of::<T::Offset>());
231 offsets.push(T::Offset::usize_as(0));
232
233 let mut values = MutableBuffer::new(0);
234 for s in iter {
235 let s: &[u8] = s.as_ref().as_ref();
236 values.extend_from_slice(s);
237 offsets.push(T::Offset::usize_as(values.len()));
238 }
239
240 T::Offset::from_usize(values.len()).expect("offset overflow");
241 let offsets = Buffer::from(offsets);
242
243 let value_offsets = unsafe { OffsetBuffer::new_unchecked(offsets.into()) };
245
246 Self {
247 data_type: T::DATA_TYPE,
248 value_data: values.into(),
249 value_offsets,
250 nulls: None,
251 }
252 }
253
254 pub fn into_parts(self) -> (OffsetBuffer<T::Offset>, Buffer, Option<NullBuffer>) {
256 (self.value_offsets, self.value_data, self.nulls)
257 }
258
259 #[inline]
263 pub fn value_length(&self, i: usize) -> T::Offset {
264 let offsets = self.value_offsets();
265 offsets[i + 1] - offsets[i]
266 }
267
268 #[inline]
273 pub fn offsets(&self) -> &OffsetBuffer<T::Offset> {
274 &self.value_offsets
275 }
276
277 #[inline]
282 pub fn values(&self) -> &Buffer {
283 &self.value_data
284 }
285
286 pub fn value_data(&self) -> &[u8] {
288 self.value_data.as_slice()
289 }
290
291 pub fn is_ascii(&self) -> bool {
293 let offsets = self.value_offsets();
294 let start = offsets.first().unwrap();
295 let end = offsets.last().unwrap();
296 self.value_data()[start.as_usize()..end.as_usize()].is_ascii()
297 }
298
299 #[inline]
301 pub fn value_offsets(&self) -> &[T::Offset] {
302 &self.value_offsets
303 }
304
305 pub unsafe fn value_unchecked(&self, i: usize) -> &T::Native {
313 let end = *unsafe { self.value_offsets().get_unchecked(i + 1) };
314 let start = *unsafe { self.value_offsets().get_unchecked(i) };
315
316 let b = unsafe {
326 std::slice::from_raw_parts(
327 self.value_data
328 .as_ptr()
329 .offset(start.to_isize().unwrap_unchecked()),
330 (end - start).to_usize().unwrap_unchecked(),
331 )
332 };
333
334 unsafe { T::Native::from_bytes_unchecked(b) }
337 }
338
339 pub fn value(&self, i: usize) -> &T::Native {
347 assert!(
348 i < self.len(),
349 "Trying to access an element at index {} from a {}{}Array of length {}",
350 i,
351 T::Offset::PREFIX,
352 T::PREFIX,
353 self.len()
354 );
355 unsafe { self.value_unchecked(i) }
358 }
359
360 pub fn iter(&self) -> ArrayIter<&Self> {
362 ArrayIter::new(self)
363 }
364
365 pub fn slice(&self, offset: usize, length: usize) -> Self {
370 Self {
371 data_type: T::DATA_TYPE,
372 value_offsets: self.value_offsets.slice(offset, length),
373 value_data: self.value_data.clone(),
374 nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
375 }
376 }
377
378 pub fn into_builder(self) -> Result<GenericByteBuilder<T>, Self> {
381 let len = self.len();
382 let value_len = T::Offset::as_usize(self.value_offsets()[len] - self.value_offsets()[0]);
383
384 let data = self.into_data();
385 let null_bit_buffer = data.nulls().map(|b| b.inner().sliced());
386
387 let element_len = std::mem::size_of::<T::Offset>();
388 let offset_buffer = data.buffers()[0]
389 .slice_with_length(data.offset() * element_len, (len + 1) * element_len);
390
391 let element_len = std::mem::size_of::<u8>();
392 let value_buffer = data.buffers()[1]
393 .slice_with_length(data.offset() * element_len, value_len * element_len);
394
395 drop(data);
396
397 let try_mutable_null_buffer = match null_bit_buffer {
398 None => Ok(None),
399 Some(null_buffer) => {
400 null_buffer.into_mutable().map(Some)
402 }
403 };
404
405 let try_mutable_buffers = match try_mutable_null_buffer {
406 Ok(mutable_null_buffer) => {
407 let try_mutable_offset_buffer = offset_buffer.into_mutable();
409 let try_mutable_value_buffer = value_buffer.into_mutable();
410
411 match (try_mutable_offset_buffer, try_mutable_value_buffer) {
414 (Ok(mutable_offset_buffer), Ok(mutable_value_buffer)) => unsafe {
415 Ok(GenericByteBuilder::<T>::new_from_buffer(
416 mutable_offset_buffer,
417 mutable_value_buffer,
418 mutable_null_buffer,
419 ))
420 },
421 (Ok(mutable_offset_buffer), Err(value_buffer)) => Err((
422 mutable_offset_buffer.into(),
423 value_buffer,
424 mutable_null_buffer.map(|b| b.into()),
425 )),
426 (Err(offset_buffer), Ok(mutable_value_buffer)) => Err((
427 offset_buffer,
428 mutable_value_buffer.into(),
429 mutable_null_buffer.map(|b| b.into()),
430 )),
431 (Err(offset_buffer), Err(value_buffer)) => Err((
432 offset_buffer,
433 value_buffer,
434 mutable_null_buffer.map(|b| b.into()),
435 )),
436 }
437 }
438 Err(mutable_null_buffer) => {
439 Err((offset_buffer, value_buffer, Some(mutable_null_buffer)))
441 }
442 };
443
444 match try_mutable_buffers {
445 Ok(builder) => Ok(builder),
446 Err((offset_buffer, value_buffer, null_bit_buffer)) => {
447 let builder = ArrayData::builder(T::DATA_TYPE)
448 .len(len)
449 .add_buffer(offset_buffer)
450 .add_buffer(value_buffer)
451 .null_bit_buffer(null_bit_buffer);
452
453 let array_data = unsafe { builder.build_unchecked() };
454 let array = GenericByteArray::<T>::from(array_data);
455
456 Err(array)
457 }
458 }
459 }
460}
461
462impl<T: ByteArrayType> std::fmt::Debug for GenericByteArray<T> {
463 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
464 write!(f, "{}{}Array\n[\n", T::Offset::PREFIX, T::PREFIX)?;
465 print_long_array(self, f, |array, index, f| {
466 std::fmt::Debug::fmt(&array.value(index), f)
467 })?;
468 write!(f, "]")
469 }
470}
471
472unsafe impl<T: ByteArrayType> Array for GenericByteArray<T> {
474 fn as_any(&self) -> &dyn Any {
475 self
476 }
477
478 fn to_data(&self) -> ArrayData {
479 self.clone().into()
480 }
481
482 fn into_data(self) -> ArrayData {
483 self.into()
484 }
485
486 fn data_type(&self) -> &DataType {
487 &self.data_type
488 }
489
490 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
491 Arc::new(self.slice(offset, length))
492 }
493
494 fn len(&self) -> usize {
495 self.value_offsets.len() - 1
496 }
497
498 fn is_empty(&self) -> bool {
499 self.value_offsets.len() <= 1
500 }
501
502 fn shrink_to_fit(&mut self) {
503 self.value_offsets.shrink_to_fit();
504 self.value_data.shrink_to_fit();
505 if let Some(nulls) = &mut self.nulls {
506 nulls.shrink_to_fit();
507 }
508 }
509
510 fn offset(&self) -> usize {
511 0
512 }
513
514 fn nulls(&self) -> Option<&NullBuffer> {
515 self.nulls.as_ref()
516 }
517
518 fn logical_null_count(&self) -> usize {
519 self.null_count()
521 }
522
523 fn get_buffer_memory_size(&self) -> usize {
524 let mut sum = self.value_offsets.inner().inner().capacity();
525 sum += self.value_data.capacity();
526 if let Some(x) = &self.nulls {
527 sum += x.buffer().capacity()
528 }
529 sum
530 }
531
532 fn get_array_memory_size(&self) -> usize {
533 std::mem::size_of::<Self>() + self.get_buffer_memory_size()
534 }
535
536 #[cfg(feature = "pool")]
537 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
538 self.value_offsets.claim(pool);
539 self.value_data.claim(pool);
540 if let Some(nulls) = &self.nulls {
541 nulls.claim(pool);
542 }
543 }
544}
545
546impl<'a, T: ByteArrayType> ArrayAccessor for &'a GenericByteArray<T> {
547 type Item = &'a T::Native;
548
549 fn value(&self, index: usize) -> Self::Item {
550 GenericByteArray::value(self, index)
551 }
552
553 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
554 unsafe { GenericByteArray::value_unchecked(self, index) }
555 }
556}
557
558impl<T: ByteArrayType> From<ArrayData> for GenericByteArray<T> {
559 fn from(data: ArrayData) -> Self {
560 let (data_type, len, nulls, offset, mut buffers, _child_data) = data.into_parts();
561 assert_eq!(
562 data_type,
563 Self::DATA_TYPE,
564 "{}{}Array expects DataType::{}",
565 T::Offset::PREFIX,
566 T::PREFIX,
567 Self::DATA_TYPE
568 );
569 assert_eq!(
570 buffers.len(),
571 2,
572 "{}{}Array data should contain 2 buffers only (offsets and values)",
573 T::Offset::PREFIX,
574 T::PREFIX,
575 );
576 let value_data = buffers.pop().expect("checked above");
578 let offset_buffer = buffers.pop().expect("checked above");
579
580 let value_offsets = unsafe { get_offsets_from_buffer(offset_buffer, offset, len) };
583 Self {
584 data_type,
585 value_offsets,
586 value_data,
587 nulls,
588 }
589 }
590}
591
592impl<T: ByteArrayType> From<GenericByteArray<T>> for ArrayData {
593 fn from(array: GenericByteArray<T>) -> Self {
594 let len = array.len();
595
596 let offsets = array.value_offsets.into_inner().into_inner();
597 let builder = ArrayDataBuilder::new(array.data_type)
598 .len(len)
599 .buffers(vec![offsets, array.value_data])
600 .nulls(array.nulls);
601
602 unsafe { builder.build_unchecked() }
603 }
604}
605
606impl<'a, T: ByteArrayType> IntoIterator for &'a GenericByteArray<T> {
607 type Item = Option<&'a T::Native>;
608 type IntoIter = ArrayIter<Self>;
609
610 fn into_iter(self) -> Self::IntoIter {
611 ArrayIter::new(self)
612 }
613}
614
615impl<'a, Ptr, T: ByteArrayType> FromIterator<&'a Option<Ptr>> for GenericByteArray<T>
616where
617 Ptr: AsRef<T::Native> + 'a,
618{
619 fn from_iter<I: IntoIterator<Item = &'a Option<Ptr>>>(iter: I) -> Self {
620 iter.into_iter()
621 .map(|o| o.as_ref().map(|p| p.as_ref()))
622 .collect()
623 }
624}
625
626impl<Ptr, T: ByteArrayType> FromIterator<Option<Ptr>> for GenericByteArray<T>
627where
628 Ptr: AsRef<T::Native>,
629{
630 fn from_iter<I: IntoIterator<Item = Option<Ptr>>>(iter: I) -> Self {
631 let iter = iter.into_iter();
632 let mut builder = GenericByteBuilder::with_capacity(iter.size_hint().0, 1024);
633 builder.extend(iter);
634 builder.finish()
635 }
636}
637
638#[cfg(test)]
639mod tests {
640 use crate::{Array, BinaryArray, StringArray};
641 use arrow_buffer::{Buffer, NullBuffer, OffsetBuffer};
642
643 #[test]
644 fn try_new() {
645 let data = Buffer::from_slice_ref("helloworld");
646 let offsets = OffsetBuffer::new(vec![0, 5, 10].into());
647 StringArray::new(offsets.clone(), data.clone(), None);
648
649 let nulls = NullBuffer::new_null(3);
650 let err =
651 StringArray::try_new(offsets.clone(), data.clone(), Some(nulls.clone())).unwrap_err();
652 assert_eq!(
653 err.to_string(),
654 "Invalid argument error: Incorrect length of null buffer for StringArray, expected 2 got 3"
655 );
656
657 let err = BinaryArray::try_new(offsets.clone(), data.clone(), Some(nulls)).unwrap_err();
658 assert_eq!(
659 err.to_string(),
660 "Invalid argument error: Incorrect length of null buffer for BinaryArray, expected 2 got 3"
661 );
662
663 let non_utf8_data = Buffer::from_slice_ref(b"he\xFFloworld");
664 let err = StringArray::try_new(offsets.clone(), non_utf8_data.clone(), None).unwrap_err();
665 assert_eq!(
666 err.to_string(),
667 "Invalid argument error: Encountered non UTF-8 data: invalid utf-8 sequence of 1 bytes from index 2"
668 );
669
670 BinaryArray::new(offsets, non_utf8_data, None);
671
672 let offsets = OffsetBuffer::new(vec![0, 5, 11].into());
673 let err = StringArray::try_new(offsets.clone(), data.clone(), None).unwrap_err();
674 assert_eq!(
675 err.to_string(),
676 "Invalid argument error: Offset of 11 exceeds length of values 10"
677 );
678
679 let err = BinaryArray::try_new(offsets.clone(), data, None).unwrap_err();
680 assert_eq!(
681 err.to_string(),
682 "Invalid argument error: Maximum offset of 11 is larger than values of length 10"
683 );
684
685 let non_ascii_data = Buffer::from_slice_ref("heìloworld");
686 StringArray::new(offsets.clone(), non_ascii_data.clone(), None);
687 BinaryArray::new(offsets, non_ascii_data.clone(), None);
688
689 let offsets = OffsetBuffer::new(vec![0, 3, 10].into());
690 let err = StringArray::try_new(offsets.clone(), non_ascii_data.clone(), None).unwrap_err();
691 assert_eq!(
692 err.to_string(),
693 "Invalid argument error: Split UTF-8 codepoint at offset 3"
694 );
695
696 BinaryArray::new(offsets, non_ascii_data, None);
697 }
698
699 #[test]
700 fn create_repeated() {
701 let arr = BinaryArray::new_repeated(b"hello", 3);
702 assert_eq!(arr.len(), 3);
703 assert_eq!(arr.value(0), b"hello");
704 assert_eq!(arr.value(1), b"hello");
705 assert_eq!(arr.value(2), b"hello");
706
707 let arr = StringArray::new_repeated("world", 2);
708 assert_eq!(arr.len(), 2);
709 assert_eq!(arr.value(0), "world");
710 assert_eq!(arr.value(1), "world");
711 }
712
713 #[test]
714 #[should_panic(expected = "usize overflow")]
715 fn create_repeated_usize_overflow_1() {
716 let _arr = BinaryArray::new_repeated(b"hello", (usize::MAX / "hello".len()) + 1);
717 }
718
719 #[test]
720 #[should_panic(expected = "usize overflow")]
721 fn create_repeated_usize_overflow_2() {
722 let _arr = BinaryArray::new_repeated(b"hello", usize::MAX);
723 }
724
725 #[test]
726 #[should_panic(expected = "offset overflow")]
727 fn create_repeated_i32_offset_overflow_1() {
728 let _arr = BinaryArray::new_repeated(b"hello", usize::MAX / "hello".len());
729 }
730
731 #[test]
732 #[should_panic(expected = "offset overflow")]
733 fn create_repeated_i32_offset_overflow_2() {
734 let _arr = BinaryArray::new_repeated(b"hello", ((i32::MAX as usize) / "hello".len()) + 1);
735 }
736}