1use std::any::Any;
2use std::fmt::{Debug, Formatter};
3use std::ops::Deref;
4
5use hashbrown::hash_map::Entry;
6use polars_buffer::Buffer;
7use polars_error::PolarsResult;
8use polars_utils::aliases::{InitHashMaps, PlHashMap};
9
10use crate::array::binview::iterator::MutableBinaryViewValueIter;
11use crate::array::binview::view::validate_views_utf8_only;
12use crate::array::binview::{
13 BinaryViewArrayGeneric, DEFAULT_BLOCK_SIZE, MAX_EXP_BLOCK_SIZE, ViewType,
14};
15use crate::array::{Array, BINVIEW_ARROW_BUFFER_LEN_LIMIT, MutableArray, TryExtend, TryPush, View};
16use crate::bitmap::MutableBitmap;
17use crate::datatypes::ArrowDataType;
18use crate::legacy::trusted_len::TrustedLenPush;
19use crate::trusted_len::TrustedLen;
20
21pub struct MutableBinaryViewArray<T: ViewType + ?Sized> {
27 pub(crate) views: Vec<View>,
28 pub(crate) completed_buffers: Vec<Buffer<u8>>,
29 pub(crate) in_progress_buffer: Vec<u8>,
30 pub(crate) validity: Option<MutableBitmap>,
31 pub(crate) phantom: std::marker::PhantomData<T>,
32 pub(crate) total_bytes_len: usize,
34 pub(crate) total_buffer_len: usize,
36 pub(crate) stolen_buffers: PlHashMap<usize, u32>,
39}
40
41impl<T: ViewType + ?Sized> Clone for MutableBinaryViewArray<T> {
42 fn clone(&self) -> Self {
43 Self {
44 views: self.views.clone(),
45 completed_buffers: self.completed_buffers.clone(),
46 in_progress_buffer: self.in_progress_buffer.clone(),
47 validity: self.validity.clone(),
48 phantom: Default::default(),
49 total_bytes_len: self.total_bytes_len,
50 total_buffer_len: self.total_buffer_len,
51 stolen_buffers: PlHashMap::new(),
52 }
53 }
54}
55
56impl<T: ViewType + ?Sized> Debug for MutableBinaryViewArray<T> {
57 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
58 write!(f, "mutable-binview{:?}", T::DATA_TYPE)
59 }
60}
61
62impl<T: ViewType + ?Sized> Default for MutableBinaryViewArray<T> {
63 fn default() -> Self {
64 Self::with_capacity(0)
65 }
66}
67
68impl<T: ViewType + ?Sized> From<MutableBinaryViewArray<T>> for BinaryViewArrayGeneric<T> {
69 fn from(mut value: MutableBinaryViewArray<T>) -> Self {
70 value.finish_in_progress();
71 unsafe {
72 Self::new_unchecked(
73 T::DATA_TYPE,
74 value.views.into(),
75 Buffer::from(value.completed_buffers),
76 value.validity.map(|b| b.into()),
77 Some(value.total_bytes_len),
78 value.total_buffer_len,
79 )
80 }
81 }
82}
83
84impl<T: ViewType + ?Sized> MutableBinaryViewArray<T> {
85 pub fn new() -> Self {
86 Self::default()
87 }
88
89 pub fn with_capacity(capacity: usize) -> Self {
90 Self {
91 views: Vec::with_capacity(capacity),
92 completed_buffers: vec![],
93 in_progress_buffer: vec![],
94 validity: None,
95 phantom: Default::default(),
96 total_buffer_len: 0,
97 total_bytes_len: 0,
98 stolen_buffers: PlHashMap::new(),
99 }
100 }
101
102 #[inline]
109 pub unsafe fn views_mut(&mut self) -> &mut Vec<View> {
110 &mut self.views
111 }
112
113 #[inline]
119 pub unsafe fn set_total_bytes_len(&mut self, value: usize) {
120 #[cfg(debug_assertions)]
121 {
122 let actual_length: usize = self.views().iter().map(|v| v.length as usize).sum();
123 assert_eq!(value, actual_length);
124 }
125
126 self.total_bytes_len = value;
127 }
128
129 pub fn total_bytes_len(&self) -> usize {
130 self.total_bytes_len
131 }
132
133 pub fn total_buffer_len(&self) -> usize {
134 self.total_buffer_len
135 }
136
137 #[inline]
138 pub fn views(&self) -> &[View] {
139 &self.views
140 }
141
142 #[inline]
143 pub fn completed_buffers(&self) -> &[Buffer<u8>] {
144 &self.completed_buffers
145 }
146
147 pub fn validity(&mut self) -> Option<&mut MutableBitmap> {
148 self.validity.as_mut()
149 }
150
151 pub fn reserve(&mut self, additional: usize) {
153 self.views.reserve(additional);
154 }
155
156 #[inline]
157 pub fn len(&self) -> usize {
158 self.views.len()
159 }
160
161 #[inline]
162 pub fn capacity(&self) -> usize {
163 self.views.capacity()
164 }
165
166 fn init_validity(&mut self, unset_last: bool) {
167 let mut validity = MutableBitmap::with_capacity(self.views.capacity());
168 validity.extend_constant(self.len(), true);
169 if unset_last {
170 validity.set(self.len() - 1, false);
171 }
172 self.validity = Some(validity);
173 }
174
175 pub(crate) unsafe fn push_view_unchecked(&mut self, v: View, buffers: &[Buffer<u8>]) {
180 let len = v.length;
181 if len <= View::MAX_INLINE_SIZE {
182 debug_assert!(self.views.capacity() > self.views.len());
183 self.views.push_unchecked(v);
184 self.total_bytes_len += len as usize;
185 } else {
186 let data = buffers.get_unchecked(v.buffer_idx as usize);
187 let offset = v.offset as usize;
188 let bytes = data.get_unchecked(offset..offset + len as usize);
189 let t = T::from_bytes_unchecked(bytes);
190 self.push_value_ignore_validity(t)
191 }
192 }
193
194 pub unsafe fn push_view_unchecked_dedupe(&mut self, mut v: View, buffers: &[Buffer<u8>]) {
200 let len = v.length;
201 self.total_bytes_len += len as usize;
202 if len <= View::MAX_INLINE_SIZE {
203 self.views.push_unchecked(v);
204 } else {
205 let buffer = buffers.get_unchecked(v.buffer_idx as usize);
206 let idx = match self.stolen_buffers.entry(buffer.deref().as_ptr() as usize) {
207 Entry::Occupied(entry) => *entry.get(),
208 Entry::Vacant(entry) => {
209 let idx = self.completed_buffers.len() as u32;
210 entry.insert(idx);
211 self.completed_buffers.push(buffer.clone());
212 self.total_buffer_len += buffer.len();
213 idx
214 },
215 };
216 v.buffer_idx = idx;
217 self.views.push_unchecked(v);
218 }
219 }
220
221 pub fn push_view(&mut self, mut v: View, buffers: &[Buffer<u8>]) {
222 let len = v.length;
223 self.total_bytes_len += len as usize;
224 if len <= View::MAX_INLINE_SIZE {
225 self.views.push(v);
226 } else {
227 self.finish_in_progress();
230
231 let buffer = &buffers[v.buffer_idx as usize];
232 let idx = match self.stolen_buffers.entry(buffer.deref().as_ptr() as usize) {
233 Entry::Occupied(entry) => {
234 let idx = *entry.get();
235 let target_buffer = &self.completed_buffers[idx as usize];
236 debug_assert_eq!(buffer, target_buffer);
237 idx
238 },
239 Entry::Vacant(entry) => {
240 let idx = self.completed_buffers.len() as u32;
241 entry.insert(idx);
242 self.completed_buffers.push(buffer.clone());
243 self.total_buffer_len += buffer.len();
244 idx
245 },
246 };
247 v.buffer_idx = idx;
248 self.views.push(v);
249 }
250 if let Some(validity) = &mut self.validity {
251 validity.push(true)
252 }
253 }
254
255 #[inline]
256 pub fn push_value_ignore_validity<V: AsRef<T>>(&mut self, value: V) {
257 let bytes = value.as_ref().to_bytes();
258 self.total_bytes_len += bytes.len();
259 let view = self.push_value_into_buffer(bytes);
260 self.views.push(view);
261 }
262
263 #[inline]
264 pub fn push_buffer(&mut self, buffer: Buffer<u8>) -> u32 {
265 self.finish_in_progress();
266
267 let buffer_idx = self.completed_buffers.len();
268 self.total_buffer_len += buffer.len();
269 self.completed_buffers.push(buffer);
270 buffer_idx as u32
271 }
272
273 #[inline]
274 pub fn push_value<V: AsRef<T>>(&mut self, value: V) {
275 if let Some(validity) = &mut self.validity {
276 validity.push(true)
277 }
278 self.push_value_ignore_validity(value)
279 }
280
281 #[inline]
282 pub fn push<V: AsRef<T>>(&mut self, value: Option<V>) {
283 if let Some(value) = value {
284 self.push_value(value)
285 } else {
286 self.push_null()
287 }
288 }
289
290 #[inline]
291 pub fn push_null(&mut self) {
292 self.views.push(View::default());
293 match &mut self.validity {
294 Some(validity) => validity.push(false),
295 None => self.init_validity(true),
296 }
297 }
298
299 pub fn push_value_into_buffer(&mut self, bytes: &[u8]) -> View {
301 assert!(bytes.len() <= u32::MAX as usize);
302
303 if bytes.len() <= View::MAX_INLINE_SIZE as usize {
304 View::new_inline(bytes)
305 } else {
306 self.total_buffer_len += bytes.len();
307
308 if self.in_progress_buffer.len().saturating_add(bytes.len())
312 > usize::min(
313 BINVIEW_ARROW_BUFFER_LEN_LIMIT,
314 self.in_progress_buffer.capacity(),
315 )
316 {
317 const {
318 assert!(MAX_EXP_BLOCK_SIZE < BINVIEW_ARROW_BUFFER_LEN_LIMIT);
319 }
320
321 let new_capacity = usize::max(
323 bytes.len(),
324 (self.in_progress_buffer.capacity() * 2)
325 .clamp(DEFAULT_BLOCK_SIZE, MAX_EXP_BLOCK_SIZE),
326 );
327
328 let in_progress = Vec::with_capacity(new_capacity);
329 let flushed = std::mem::replace(&mut self.in_progress_buffer, in_progress);
330 if !flushed.is_empty() {
331 self.completed_buffers.push(flushed.into())
332 }
333 }
334
335 let offset = self.in_progress_buffer.len() as u32;
336 self.in_progress_buffer.extend_from_slice(bytes);
337
338 let buffer_idx = u32::try_from(self.completed_buffers.len()).unwrap();
339
340 View::new_from_bytes(bytes, buffer_idx, offset)
341 }
342 }
343
344 pub fn extend_null(&mut self, additional: usize) {
345 if self.validity.is_none() && additional > 0 {
346 self.init_validity(false);
347 }
348 self.views
349 .extend(std::iter::repeat_n(View::default(), additional));
350 if let Some(validity) = &mut self.validity {
351 validity.extend_constant(additional, false);
352 }
353 }
354
355 pub fn extend_constant<V: AsRef<T>>(&mut self, additional: usize, value: Option<V>) {
356 if value.is_none() && self.validity.is_none() {
357 self.init_validity(false);
358 }
359
360 if let Some(validity) = &mut self.validity {
361 validity.extend_constant(additional, value.is_some())
362 }
363
364 if let Some(bytes) = value {
368 let view = self.push_value_into_buffer(bytes.as_ref().to_bytes());
369 self.views.extend(std::iter::repeat_n(view, additional));
370 self.total_bytes_len += view.length as usize * additional;
371 }
372 }
373
374 impl_mutable_array_mut_validity!();
375
376 #[inline]
377 pub fn extend_values<I, P>(&mut self, iterator: I)
378 where
379 I: Iterator<Item = P>,
380 P: AsRef<T>,
381 {
382 self.reserve(iterator.size_hint().0);
383 for v in iterator {
384 self.push_value(v)
385 }
386 }
387
388 #[inline]
389 pub fn extend_trusted_len_values<I, P>(&mut self, iterator: I)
390 where
391 I: TrustedLen<Item = P>,
392 P: AsRef<T>,
393 {
394 self.extend_values(iterator)
395 }
396
397 #[inline]
398 pub fn extend<I, P>(&mut self, iterator: I)
399 where
400 I: Iterator<Item = Option<P>>,
401 P: AsRef<T>,
402 {
403 self.reserve(iterator.size_hint().0);
404 for p in iterator {
405 self.push(p)
406 }
407 }
408
409 #[inline]
410 pub fn extend_trusted_len<I, P>(&mut self, iterator: I)
411 where
412 I: TrustedLen<Item = Option<P>>,
413 P: AsRef<T>,
414 {
415 self.extend(iterator)
416 }
417
418 #[inline]
419 pub fn extend_views<I>(&mut self, iterator: I, buffers: &[Buffer<u8>])
420 where
421 I: Iterator<Item = Option<View>>,
422 {
423 self.reserve(iterator.size_hint().0);
424 for p in iterator {
425 match p {
426 Some(v) => self.push_view(v, buffers),
427 None => self.push_null(),
428 }
429 }
430 }
431
432 #[inline]
433 pub fn extend_views_trusted_len<I>(&mut self, iterator: I, buffers: &[Buffer<u8>])
434 where
435 I: TrustedLen<Item = Option<View>>,
436 {
437 self.extend_views(iterator, buffers);
438 }
439
440 #[inline]
441 pub fn extend_non_null_views<I>(&mut self, iterator: I, buffers: &[Buffer<u8>])
442 where
443 I: Iterator<Item = View>,
444 {
445 self.reserve(iterator.size_hint().0);
446 for v in iterator {
447 self.push_view(v, buffers);
448 }
449 }
450
451 #[inline]
452 pub fn extend_non_null_views_trusted_len<I>(&mut self, iterator: I, buffers: &[Buffer<u8>])
453 where
454 I: TrustedLen<Item = View>,
455 {
456 self.extend_non_null_views(iterator, buffers);
457 }
458
459 #[inline]
462 pub unsafe fn extend_non_null_views_unchecked<I>(&mut self, iterator: I, buffers: &[Buffer<u8>])
463 where
464 I: Iterator<Item = View>,
465 {
466 self.reserve(iterator.size_hint().0);
467 for v in iterator {
468 self.push_view_unchecked(v, buffers);
469 }
470 }
471
472 #[inline]
475 pub unsafe fn extend_non_null_views_unchecked_dedupe<I>(
476 &mut self,
477 iterator: I,
478 buffers: &[Buffer<u8>],
479 ) where
480 I: Iterator<Item = View>,
481 {
482 self.reserve(iterator.size_hint().0);
483 for v in iterator {
484 self.push_view_unchecked_dedupe(v, buffers);
485 }
486 }
487
488 #[inline]
489 pub fn from_iterator<I, P>(iterator: I) -> Self
490 where
491 I: Iterator<Item = Option<P>>,
492 P: AsRef<T>,
493 {
494 let mut mutable = Self::with_capacity(iterator.size_hint().0);
495 mutable.extend(iterator);
496 mutable
497 }
498
499 pub fn from_values_iter<I, P>(iterator: I) -> Self
500 where
501 I: Iterator<Item = P>,
502 P: AsRef<T>,
503 {
504 let mut mutable = Self::with_capacity(iterator.size_hint().0);
505 mutable.extend_values(iterator);
506 mutable
507 }
508
509 pub fn from<S: AsRef<T>, P: AsRef<[Option<S>]>>(slice: P) -> Self {
510 Self::from_iterator(slice.as_ref().iter().map(|opt_v| opt_v.as_ref()))
511 }
512
513 pub fn finish_in_progress(&mut self) -> bool {
514 if !self.in_progress_buffer.is_empty() {
515 self.completed_buffers
516 .push(std::mem::take(&mut self.in_progress_buffer).into());
517 true
518 } else {
519 false
520 }
521 }
522
523 #[inline]
524 pub fn freeze(self) -> BinaryViewArrayGeneric<T> {
525 self.into()
526 }
527
528 #[inline]
529 pub fn freeze_with_dtype(self, dtype: ArrowDataType) -> BinaryViewArrayGeneric<T> {
530 let mut arr: BinaryViewArrayGeneric<T> = self.into();
531 arr.dtype = dtype;
532 arr
533 }
534
535 pub fn take(self) -> (Vec<View>, Vec<Buffer<u8>>) {
536 (self.views, self.completed_buffers)
537 }
538
539 #[inline]
540 pub fn value(&self, i: usize) -> &T {
541 assert!(i < self.len());
542 unsafe { self.value_unchecked(i) }
543 }
544
545 #[inline]
550 pub unsafe fn value_unchecked(&self, i: usize) -> &T {
551 self.value_from_view_unchecked(self.views.get_unchecked(i))
552 }
553
554 pub unsafe fn value_from_view_unchecked<'a>(&'a self, view: &'a View) -> &'a T {
559 let len = view.length;
569 let bytes = if len <= View::MAX_INLINE_SIZE {
570 let ptr = view as *const View as *const u8;
571 std::slice::from_raw_parts(ptr.add(4), len as usize)
572 } else {
573 let buffer_idx = view.buffer_idx as usize;
574 let offset = view.offset;
575
576 let data = if buffer_idx == self.completed_buffers.len() {
577 self.in_progress_buffer.as_slice()
578 } else {
579 self.completed_buffers.get_unchecked(buffer_idx)
580 };
581
582 let offset = offset as usize;
583 data.get_unchecked(offset..offset + len as usize)
584 };
585 T::from_bytes_unchecked(bytes)
586 }
587
588 pub fn values_iter(&self) -> MutableBinaryViewValueIter<'_, T> {
590 MutableBinaryViewValueIter::new(self)
591 }
592
593 pub fn extend_from_array(&mut self, other: &BinaryViewArrayGeneric<T>) {
594 let slf_len = self.len();
595 match (&mut self.validity, other.validity()) {
596 (None, None) => {},
597 (Some(v), None) => v.extend_constant(other.len(), true),
598 (v @ None, Some(other)) => {
599 let mut bm = MutableBitmap::with_capacity(slf_len + other.len());
600 bm.extend_constant(slf_len, true);
601 bm.extend_from_bitmap(other);
602 *v = Some(bm);
603 },
604 (Some(slf), Some(other)) => slf.extend_from_bitmap(other),
605 }
606
607 if other.total_buffer_len() == 0 {
608 self.views.extend(other.views().iter().copied());
609 } else {
610 self.finish_in_progress();
611
612 let buffer_offset = self.completed_buffers().len() as u32;
613 self.completed_buffers
614 .extend(other.data_buffers().iter().cloned());
615
616 self.views.extend(other.views().iter().map(|view| {
617 let mut view = *view;
618 if view.length > View::MAX_INLINE_SIZE {
619 view.buffer_idx += buffer_offset;
620 }
621 view
622 }));
623
624 let new_total_buffer_len = self.total_buffer_len() + other.total_buffer_len();
625 self.total_buffer_len = new_total_buffer_len;
626 }
627
628 self.total_bytes_len = self.total_bytes_len() + other.total_bytes_len();
629 }
630}
631
632impl MutableBinaryViewArray<[u8]> {
633 pub fn validate_utf8(&mut self, buffer_offset: usize, views_offset: usize) -> PolarsResult<()> {
634 let pushed = self.finish_in_progress();
636 unsafe {
638 validate_views_utf8_only(
639 &self.views[views_offset..],
640 &self.completed_buffers,
641 buffer_offset,
642 )?
643 }
644 if pushed {
646 if let Some(last) = self.completed_buffers.pop() {
647 self.in_progress_buffer = last.into_mut().right().unwrap();
648 }
649 }
650 Ok(())
651 }
652}
653
654impl<T: ViewType + ?Sized, P: AsRef<T>> Extend<Option<P>> for MutableBinaryViewArray<T> {
655 #[inline]
656 fn extend<I: IntoIterator<Item = Option<P>>>(&mut self, iter: I) {
657 Self::extend(self, iter.into_iter())
658 }
659}
660
661impl<T: ViewType + ?Sized, P: AsRef<T>> FromIterator<Option<P>> for MutableBinaryViewArray<T> {
662 #[inline]
663 fn from_iter<I: IntoIterator<Item = Option<P>>>(iter: I) -> Self {
664 Self::from_iterator(iter.into_iter())
665 }
666}
667
668impl<T: ViewType + ?Sized> MutableArray for MutableBinaryViewArray<T> {
669 fn dtype(&self) -> &ArrowDataType {
670 T::dtype()
671 }
672
673 fn len(&self) -> usize {
674 MutableBinaryViewArray::len(self)
675 }
676
677 fn validity(&self) -> Option<&MutableBitmap> {
678 self.validity.as_ref()
679 }
680
681 fn as_box(&mut self) -> Box<dyn Array> {
682 let mutable = std::mem::take(self);
683 let arr: BinaryViewArrayGeneric<T> = mutable.into();
684 arr.boxed()
685 }
686
687 fn as_any(&self) -> &dyn Any {
688 self
689 }
690
691 fn as_mut_any(&mut self) -> &mut dyn Any {
692 self
693 }
694
695 fn push_null(&mut self) {
696 MutableBinaryViewArray::push_null(self)
697 }
698
699 fn reserve(&mut self, additional: usize) {
700 MutableBinaryViewArray::reserve(self, additional)
701 }
702
703 fn shrink_to_fit(&mut self) {
704 self.views.shrink_to_fit()
705 }
706}
707
708impl<T: ViewType + ?Sized, P: AsRef<T>> TryExtend<Option<P>> for MutableBinaryViewArray<T> {
709 #[inline]
711 fn try_extend<I: IntoIterator<Item = Option<P>>>(&mut self, iter: I) -> PolarsResult<()> {
712 self.extend(iter.into_iter());
713 Ok(())
714 }
715}
716
717impl<T: ViewType + ?Sized, P: AsRef<T>> TryPush<Option<P>> for MutableBinaryViewArray<T> {
718 #[inline(always)]
720 fn try_push(&mut self, item: Option<P>) -> PolarsResult<()> {
721 self.push(item.as_ref().map(|p| p.as_ref()));
722 Ok(())
723 }
724}