1use std::alloc::Layout;
19use std::mem;
20use std::ptr::NonNull;
21
22use crate::alloc::{ALIGNMENT, Deallocation};
23use crate::{
24 bytes::Bytes,
25 native::{ArrowNativeType, ToByteSlice},
26 util::bit_util,
27};
28
29#[cfg(feature = "pool")]
30use crate::pool::{MemoryPool, MemoryReservation, lock_reservation};
31#[cfg(feature = "pool")]
32use std::sync::Mutex;
33
34use super::Buffer;
35
36#[derive(Debug, Clone, PartialEq, Eq)]
38pub enum MutableBufferError {
39 LengthOverflow,
41 LayoutError,
43 AllocationError(Layout),
45}
46
47impl std::fmt::Display for MutableBufferError {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 match self {
50 Self::LengthOverflow => write!(f, "buffer length overflow"),
51 Self::LayoutError => write!(f, "invalid allocation layout for requested capacity"),
52 Self::AllocationError(layout) => {
53 write!(f, "failed to allocate memory for layout {layout:?}")
54 }
55 }
56 }
57}
58
59impl std::error::Error for MutableBufferError {}
60
61#[derive(Debug)]
124pub struct MutableBuffer {
125 data: NonNull<u8>,
127 len: usize,
129 layout: Layout,
130
131 #[cfg(feature = "pool")]
133 reservation: Mutex<Option<Box<dyn MemoryReservation>>>,
134}
135
136impl MutableBuffer {
137 #[inline]
145 pub fn new(capacity: usize) -> Self {
146 Self::try_with_capacity(capacity).unwrap_or_else(|e| panic!("{e}"))
147 }
148
149 #[inline]
156 pub fn with_capacity(capacity: usize) -> Self {
157 Self::try_with_capacity(capacity).unwrap_or_else(|e| panic!("{e}"))
158 }
159
160 #[inline]
162 pub fn try_with_capacity(capacity: usize) -> Result<Self, MutableBufferError> {
163 let capacity = capacity
164 .checked_next_multiple_of(64)
165 .ok_or(MutableBufferError::LayoutError)?;
166 let layout = Layout::from_size_align(capacity, ALIGNMENT)
167 .map_err(|_| MutableBufferError::LayoutError)?;
168 let data = match layout.size() {
169 0 => dangling_ptr(),
170 _ => {
171 let raw_ptr = unsafe { std::alloc::alloc(layout) };
173 match NonNull::new(raw_ptr) {
174 Some(ptr) => ptr,
175 None => return Err(MutableBufferError::AllocationError(layout)),
176 }
177 }
178 };
179 Ok(Self {
180 data,
181 len: 0,
182 layout,
183 #[cfg(feature = "pool")]
184 reservation: std::sync::Mutex::new(None),
185 })
186 }
187
188 pub fn from_len_zeroed(len: usize) -> Self {
204 Self::try_from_len_zeroed(len).unwrap_or_else(|e| panic!("{e}"))
205 }
206
207 pub fn try_from_len_zeroed(len: usize) -> Result<Self, MutableBufferError> {
209 let layout =
210 Layout::from_size_align(len, ALIGNMENT).map_err(|_| MutableBufferError::LayoutError)?;
211 let data = match layout.size() {
212 0 => dangling_ptr(),
213 _ => {
214 let raw_ptr = unsafe { std::alloc::alloc_zeroed(layout) };
216 match NonNull::new(raw_ptr) {
217 Some(ptr) => ptr,
218 None => return Err(MutableBufferError::AllocationError(layout)),
219 }
220 }
221 };
222 Ok(Self {
223 data,
224 len,
225 layout,
226 #[cfg(feature = "pool")]
227 reservation: std::sync::Mutex::new(None),
228 })
229 }
230
231 pub(crate) fn from_bytes(bytes: Bytes) -> Result<Self, Bytes> {
233 let layout = match bytes.deallocation() {
234 Deallocation::Standard(layout) => *layout,
235 Deallocation::Custom(..) => return Err(bytes),
236 };
237
238 let len = bytes.len();
239 let data = bytes.ptr();
240 #[cfg(feature = "pool")]
241 let reservation = lock_reservation(&bytes.reservation).take();
242 mem::forget(bytes);
243
244 Ok(Self {
245 data,
246 len,
247 layout,
248 #[cfg(feature = "pool")]
249 reservation: Mutex::new(reservation),
250 })
251 }
252
253 pub fn new_null(len: usize) -> Self {
260 let num_bytes = bit_util::ceil(len, 8);
261 MutableBuffer::from_len_zeroed(num_bytes)
262 }
263
264 pub fn with_bitset(mut self, end: usize, val: bool) -> Self {
275 assert!(end <= self.layout.size());
276 let v = if val { 255 } else { 0 };
277 unsafe {
278 std::ptr::write_bytes(self.data.as_ptr(), v, end);
279 self.len = end;
280 }
281 self
282 }
283
284 pub fn set_null_bits(&mut self, start: usize, count: usize) {
294 assert!(
295 start.saturating_add(count) <= self.layout.size(),
296 "range start index {start} and count {count} out of bounds for \
297 buffer of length {}",
298 self.layout.size(),
299 );
300
301 unsafe {
303 std::ptr::write_bytes(self.data.as_ptr().add(start), 0, count);
304 }
305 }
306
307 #[inline]
309 pub fn try_reserve(&mut self, additional: usize) -> Result<(), MutableBufferError> {
310 let required_cap = self
311 .len
312 .checked_add(additional)
313 .ok_or(MutableBufferError::LengthOverflow)?;
314 if required_cap > self.layout.size() {
315 let new_capacity = required_cap
316 .checked_next_multiple_of(64)
317 .ok_or(MutableBufferError::LayoutError)?;
318 let new_capacity = std::cmp::max(new_capacity, self.layout.size().saturating_mul(2));
319 self.try_reallocate(new_capacity)?;
320 }
321 Ok(())
322 }
323 #[inline(always)]
342 pub fn reserve(&mut self, additional: usize) {
343 self.try_reserve(additional)
344 .unwrap_or_else(|e| panic!("{e}"))
345 }
346
347 pub fn try_repeat_slice_n_times<T: ArrowNativeType>(
349 &mut self,
350 slice_to_repeat: &[T],
351 repeat_count: usize,
352 ) -> Result<(), MutableBufferError> {
353 if repeat_count == 0 || slice_to_repeat.is_empty() {
354 return Ok(());
355 }
356 let bytes_per_copy = size_of_val(slice_to_repeat);
357 let total_bytes = repeat_count
358 .checked_mul(bytes_per_copy)
359 .ok_or(MutableBufferError::LengthOverflow)?;
360 self.len
361 .checked_add(total_bytes)
362 .ok_or(MutableBufferError::LengthOverflow)?;
363
364 self.try_reserve(total_bytes)?;
366
367 let length_before = self.len;
369
370 self.try_extend_from_slice(slice_to_repeat)?;
372
373 let mut already_repeated = 1usize;
375
376 while already_repeated < repeat_count {
378 let to_copy = already_repeated.min(repeat_count - already_repeated);
381 let byte_count = to_copy * bytes_per_copy;
382 unsafe {
383 let src = self.data.as_ptr().add(length_before).cast_const();
385 let dst = self.data.as_ptr().add(self.len);
387 std::ptr::copy_nonoverlapping(src, dst, byte_count);
389 }
390 self.len += byte_count;
392 already_repeated += to_copy;
393 }
394 Ok(())
395 }
396 pub fn repeat_slice_n_times<T: ArrowNativeType>(
415 &mut self,
416 slice_to_repeat: &[T],
417 repeat_count: usize,
418 ) {
419 self.try_repeat_slice_n_times(slice_to_repeat, repeat_count)
420 .unwrap_or_else(|e| panic!("{e}"))
421 }
422
423 #[cold]
424 fn try_reallocate(&mut self, capacity: usize) -> Result<(), MutableBufferError> {
425 let new_layout = Layout::from_size_align(capacity, self.layout.align())
426 .map_err(|_| MutableBufferError::LayoutError)?;
427
428 if new_layout.size() == 0 {
429 if self.layout.size() != 0 {
430 unsafe { std::alloc::dealloc(self.as_mut_ptr(), self.layout) };
432 self.layout = new_layout;
433 }
434 return Ok(());
435 }
436
437 let data = match self.layout.size() {
438 0 => unsafe { std::alloc::alloc(new_layout) },
440 _ => unsafe { std::alloc::realloc(self.as_mut_ptr(), self.layout, capacity) },
442 };
443 self.data = match NonNull::new(data) {
444 Some(ptr) => ptr,
445 None => return Err(MutableBufferError::AllocationError(new_layout)),
446 };
447 self.layout = new_layout;
448 #[cfg(feature = "pool")]
449 {
450 if let Some(reservation) = lock_reservation(&self.reservation).as_mut() {
451 reservation.resize(self.layout.size());
452 }
453 }
454 Ok(())
455 }
456 #[inline(always)]
460 pub fn truncate(&mut self, len: usize) {
461 if len > self.len {
462 return;
463 }
464 self.len = len;
465 #[cfg(feature = "pool")]
466 {
467 if let Some(reservation) = lock_reservation(&self.reservation).as_mut() {
468 reservation.resize(self.len);
469 }
470 }
471 }
472
473 #[inline]
475 pub fn try_resize(&mut self, new_len: usize, value: u8) -> Result<(), MutableBufferError> {
476 if new_len > self.len {
477 let diff = new_len - self.len;
478 self.try_reserve(diff)?;
479 unsafe { self.data.as_ptr().add(self.len).write_bytes(value, diff) };
482 }
483 self.len = new_len;
485 #[cfg(feature = "pool")]
486 {
487 if let Some(reservation) = lock_reservation(&self.reservation).as_mut() {
488 reservation.resize(self.len);
489 }
490 }
491 Ok(())
492 }
493 #[inline(always)]
510 pub fn resize(&mut self, new_len: usize, value: u8) {
511 self.try_resize(new_len, value)
512 .unwrap_or_else(|e| panic!("{e}"))
513 }
514
515 pub fn try_shrink_to_fit(&mut self) -> Result<(), MutableBufferError> {
517 let new_capacity = self
518 .len
519 .checked_next_multiple_of(64)
520 .ok_or(MutableBufferError::LayoutError)?;
521 if new_capacity < self.layout.size() {
522 self.try_reallocate(new_capacity)?;
523 }
524 Ok(())
525 }
526 pub fn shrink_to_fit(&mut self) {
547 self.try_shrink_to_fit().unwrap_or_else(|e| panic!("{e}"))
548 }
549
550 #[inline]
552 pub const fn is_empty(&self) -> bool {
553 self.len == 0
554 }
555
556 #[inline]
559 pub const fn len(&self) -> usize {
560 self.len
561 }
562
563 #[inline]
567 pub const fn capacity(&self) -> usize {
568 self.layout.size()
569 }
570
571 pub fn clear(&mut self) {
573 self.len = 0;
574 #[cfg(feature = "pool")]
575 {
576 if let Some(reservation) = lock_reservation(&self.reservation).as_mut() {
577 reservation.resize(self.len);
578 }
579 }
580 }
581
582 pub fn as_slice(&self) -> &[u8] {
584 self
585 }
586
587 pub fn as_slice_mut(&mut self) -> &mut [u8] {
589 self
590 }
591
592 #[inline]
595 pub const fn as_ptr(&self) -> *const u8 {
596 self.data.as_ptr()
597 }
598
599 #[inline]
602 pub fn as_mut_ptr(&mut self) -> *mut u8 {
603 self.data.as_ptr()
604 }
605
606 #[inline]
607 pub(super) fn into_buffer(self) -> Buffer {
608 let bytes = unsafe { Bytes::new(self.data, self.len, Deallocation::Standard(self.layout)) };
609 #[cfg(feature = "pool")]
610 {
611 let reservation = lock_reservation(&self.reservation).take();
612 *lock_reservation(&bytes.reservation) = reservation;
613 }
614 std::mem::forget(self);
615 Buffer::from(bytes)
616 }
617
618 pub fn typed_data_mut<T: ArrowNativeType>(&mut self) -> &mut [T] {
625 let (prefix, offsets, suffix) = unsafe { self.as_slice_mut().align_to_mut::<T>() };
629 assert!(prefix.is_empty() && suffix.is_empty());
630 offsets
631 }
632
633 pub fn typed_data<T: ArrowNativeType>(&self) -> &[T] {
640 let (prefix, offsets, suffix) = unsafe { self.as_slice().align_to::<T>() };
644 assert!(prefix.is_empty() && suffix.is_empty());
645 offsets
646 }
647
648 #[inline]
650 pub fn try_extend_from_slice<T: ArrowNativeType>(
651 &mut self,
652 items: &[T],
653 ) -> Result<(), MutableBufferError> {
654 let additional = mem::size_of_val(items);
655 self.try_reserve(additional)?;
656 unsafe {
657 let src = items.as_ptr().cast::<u8>();
661 let dst = self.data.as_ptr().add(self.len);
662 std::ptr::copy_nonoverlapping(src, dst, additional);
663 }
664 self.len += additional;
665 Ok(())
666 }
667 #[inline]
681 pub fn extend_from_slice<T: ArrowNativeType>(&mut self, items: &[T]) {
682 self.try_extend_from_slice(items)
683 .unwrap_or_else(|e| panic!("{e}"))
684 }
685
686 #[inline]
700 pub fn push<T: ToByteSlice>(&mut self, item: T) {
701 let additional = std::mem::size_of::<T>();
702 self.reserve(additional);
703 unsafe {
704 let src = item.to_byte_slice().as_ptr();
705 let dst = self.data.as_ptr().add(self.len);
706 std::ptr::copy_nonoverlapping(src, dst, additional);
707 }
708 self.len += additional;
709 }
710
711 #[inline]
715 pub unsafe fn push_unchecked<T: ToByteSlice>(&mut self, item: T) {
716 let additional = std::mem::size_of::<T>();
717 let src = item.to_byte_slice().as_ptr();
718 let dst = unsafe { self.data.as_ptr().add(self.len) };
719 unsafe { std::ptr::copy_nonoverlapping(src, dst, additional) };
720 self.len += additional;
721 }
722
723 #[inline]
725 pub fn try_extend_zeros(&mut self, additional: usize) -> Result<(), MutableBufferError> {
726 let new_len = self
727 .len
728 .checked_add(additional)
729 .ok_or(MutableBufferError::LengthOverflow)?;
730 self.try_resize(new_len, 0)
731 }
732 #[inline]
739 pub fn extend_zeros(&mut self, additional: usize) {
740 self.try_extend_zeros(additional)
741 .unwrap_or_else(|e| panic!("{e}"))
742 }
743
744 #[inline]
751 pub unsafe fn set_len(&mut self, len: usize) {
752 assert!(len <= self.capacity());
753 self.len = len;
754 }
755
756 #[inline]
761 pub fn collect_bool<F: FnMut(usize) -> bool>(len: usize, mut f: F) -> Self {
762 let mut buffer: Vec<u64> = Vec::with_capacity(bit_util::ceil(len, 64));
763
764 let chunks = len / 64;
765 let remainder = len % 64;
766 buffer.extend((0..chunks).map(|chunk| {
767 let mut packed = 0;
768 for bit_idx in 0..64 {
769 let i = bit_idx + chunk * 64;
770 packed |= (f(i) as u64) << bit_idx;
771 }
772
773 packed
774 }));
775
776 if remainder != 0 {
777 let mut packed = 0;
778 for bit_idx in 0..remainder {
779 let i = bit_idx + chunks * 64;
780 packed |= (f(i) as u64) << bit_idx;
781 }
782
783 buffer.push(packed)
784 }
785
786 let mut buffer: MutableBuffer = buffer.into();
787 buffer.truncate(bit_util::ceil(len, 8));
788 buffer
789 }
790
791 #[inline]
810 pub unsafe fn extend_bool_trusted_len<I: Iterator<Item = bool>>(
811 &mut self,
812 mut iter: I,
813 offset: usize,
814 ) {
815 let (lower, upper) = iter.size_hint();
816 let len = upper.expect("Iterator must have exact size_hint");
817 assert_eq!(lower, len, "Iterator must have exact size_hint");
818 debug_assert!(
819 offset <= self.len * 8,
820 "offset must be <= buffer length in bits"
821 );
822
823 if len == 0 {
824 return;
825 }
826
827 let start_len = offset;
828 let end_bit = start_len + len;
829
830 let new_len_bytes = bit_util::ceil(end_bit, 8);
832 if new_len_bytes > self.len {
833 self.reserve(new_len_bytes - self.len);
834 unsafe { self.set_len(new_len_bytes) };
836 }
837
838 let slice = self.as_slice_mut();
839
840 let mut bit_idx = start_len;
841
842 let misalignment = bit_idx & 63;
844 let prefix_bits = if misalignment == 0 {
845 0
846 } else {
847 (64 - misalignment).min(end_bit - bit_idx)
848 };
849
850 if prefix_bits != 0 {
851 let byte_start = bit_idx / 8;
852 let byte_end = bit_util::ceil(bit_idx + prefix_bits, 8);
853 let bit_offset = bit_idx % 8;
854
855 if bit_offset != 0 {
857 let keep_mask = (1u8 << bit_offset).wrapping_sub(1);
858 slice[byte_start] &= keep_mask;
859 }
860
861 let zero_from = if bit_offset == 0 {
863 byte_start
864 } else {
865 byte_start + 1
866 };
867 if byte_end > zero_from {
868 slice[zero_from..byte_end].fill(0);
869 }
870
871 for _ in 0..prefix_bits {
872 let v = iter.next().unwrap();
873 if v {
874 let byte_idx = bit_idx / 8;
875 let bit = bit_idx % 8;
876 slice[byte_idx] |= 1 << bit;
877 }
878 bit_idx += 1;
879 }
880 }
881
882 if bit_idx < end_bit {
883 debug_assert_eq!(bit_idx & 63, 0);
885 let remaining_bits = end_bit - bit_idx;
886 let chunks = remaining_bits / 64;
887
888 let words_start = bit_idx / 8;
889 let words_end = words_start + chunks * 8;
890 for dst in slice[words_start..words_end].chunks_exact_mut(8) {
891 let mut packed: u64 = 0;
892 for i in 0..64 {
893 packed |= (iter.next().unwrap() as u64) << i;
894 }
895 dst.copy_from_slice(&packed.to_le_bytes());
896 bit_idx += 64;
897 }
898
899 let suffix_bits = end_bit - bit_idx;
901 if suffix_bits != 0 {
902 debug_assert_eq!(bit_idx % 8, 0);
903 let byte_start = bit_idx / 8;
904 let byte_end = bit_util::ceil(end_bit, 8);
905 slice[byte_start..byte_end].fill(0);
906
907 for _ in 0..suffix_bits {
908 let v = iter.next().unwrap();
909 if v {
910 let byte_idx = bit_idx / 8;
911 let bit = bit_idx % 8;
912 slice[byte_idx] |= 1 << bit;
913 }
914 bit_idx += 1;
915 }
916 }
917 }
918
919 let remainder = end_bit % 8;
921 if remainder != 0 {
922 let mask = (1u8 << remainder).wrapping_sub(1);
923 slice[bit_util::ceil(end_bit, 8) - 1] &= mask;
924 }
925
926 debug_assert_eq!(bit_idx, end_bit);
927 }
928
929 #[cfg(feature = "pool")]
936 pub fn claim(&self, pool: &dyn MemoryPool) {
937 *lock_reservation(&self.reservation) = Some(pool.reserve(self.capacity()));
938 }
939}
940
941#[inline]
945pub(crate) fn dangling_ptr() -> NonNull<u8> {
946 #[cfg(miri)]
950 {
951 unsafe { NonNull::new_unchecked(std::ptr::without_provenance_mut(ALIGNMENT)) }
953 }
954 #[cfg(not(miri))]
955 {
956 unsafe { NonNull::new_unchecked(ALIGNMENT as *mut u8) }
957 }
958}
959
960impl<A: ArrowNativeType> Extend<A> for MutableBuffer {
961 #[inline]
962 fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
963 let iterator = iter.into_iter();
964 self.extend_from_iter(iterator)
965 }
966}
967
968impl<T: ArrowNativeType> From<Vec<T>> for MutableBuffer {
969 fn from(mut value: Vec<T>) -> Self {
970 let data = unsafe { NonNull::new_unchecked(value.as_mut_ptr().cast()) };
973 let len = value.len() * mem::size_of::<T>();
974 let layout = unsafe { Layout::array::<T>(value.capacity()).unwrap_unchecked() };
978 mem::forget(value);
979 Self {
980 data,
981 len,
982 layout,
983 #[cfg(feature = "pool")]
984 reservation: std::sync::Mutex::new(None),
985 }
986 }
987}
988
989impl MutableBuffer {
990 #[inline]
991 pub(super) fn extend_from_iter<T: ArrowNativeType, I: Iterator<Item = T>>(
992 &mut self,
993 mut iterator: I,
994 ) {
995 let item_size = std::mem::size_of::<T>();
996 let (lower, _) = iterator.size_hint();
997 let additional = lower * item_size;
998 self.reserve(additional);
999
1000 let mut len = SetLenOnDrop::new(&mut self.len);
1002 let mut dst = unsafe { self.data.as_ptr().add(len.local_len) };
1003 let capacity = self.layout.size();
1004
1005 while len.local_len + item_size <= capacity {
1006 if let Some(item) = iterator.next() {
1007 unsafe {
1008 let src = item.to_byte_slice().as_ptr();
1009 std::ptr::copy_nonoverlapping(src, dst, item_size);
1010 dst = dst.add(item_size);
1011 }
1012 len.local_len += item_size;
1013 } else {
1014 break;
1015 }
1016 }
1017 drop(len);
1018
1019 iterator.for_each(|item| self.push(item));
1020 }
1021
1022 #[inline]
1047 pub unsafe fn from_trusted_len_iter<T: ArrowNativeType, I: Iterator<Item = T>>(
1048 iterator: I,
1049 ) -> Self {
1050 let item_size = std::mem::size_of::<T>();
1051 let (_, upper) = iterator.size_hint();
1052 let upper = upper.expect("from_trusted_len_iter requires an upper limit");
1053 let len = upper * item_size;
1054
1055 let mut buffer = MutableBuffer::new(len);
1056
1057 let mut dst = buffer.data.as_ptr();
1058 for item in iterator {
1059 let src = item.to_byte_slice().as_ptr();
1061 unsafe { std::ptr::copy_nonoverlapping(src, dst, item_size) };
1062 dst = unsafe { dst.add(item_size) };
1063 }
1064 assert_eq!(
1065 unsafe { dst.offset_from(buffer.data.as_ptr()) } as usize,
1066 len,
1067 "Trusted iterator length was not accurately reported"
1068 );
1069 buffer.len = len;
1070 buffer
1071 }
1072
1073 #[inline]
1097 pub unsafe fn from_trusted_len_iter_bool<I: Iterator<Item = bool>>(mut iterator: I) -> Self {
1098 let (_, upper) = iterator.size_hint();
1099 let len = upper.expect("from_trusted_len_iter requires an upper limit");
1100
1101 Self::collect_bool(len, |_| iterator.next().unwrap())
1102 }
1103
1104 #[inline]
1126 pub unsafe fn try_from_trusted_len_iter<
1127 E,
1128 T: ArrowNativeType,
1129 I: Iterator<Item = Result<T, E>>,
1130 >(
1131 iterator: I,
1132 ) -> Result<Self, E> {
1133 let item_size = std::mem::size_of::<T>();
1134 let (_, upper) = iterator.size_hint();
1135 let upper = upper.expect("try_from_trusted_len_iter requires an upper limit");
1136 let len = upper * item_size;
1137
1138 let mut buffer = MutableBuffer::new(len);
1139
1140 let mut dst = buffer.data.as_ptr();
1141 for item in iterator {
1142 let item = item?;
1143 let src = item.to_byte_slice().as_ptr();
1145 unsafe { std::ptr::copy_nonoverlapping(src, dst, item_size) };
1146 dst = unsafe { dst.add(item_size) };
1147 }
1148 unsafe fn finalize_buffer(dst: *mut u8, buffer: &mut MutableBuffer, len: usize) {
1151 unsafe {
1152 assert_eq!(
1153 dst.offset_from(buffer.data.as_ptr()) as usize,
1154 len,
1155 "Trusted iterator length was not accurately reported"
1156 );
1157 buffer.len = len;
1158 }
1159 }
1160 unsafe { finalize_buffer(dst, &mut buffer, len) };
1161 Ok(buffer)
1162 }
1163}
1164
1165impl Default for MutableBuffer {
1166 fn default() -> Self {
1167 Self::with_capacity(0)
1168 }
1169}
1170
1171impl std::ops::Deref for MutableBuffer {
1172 type Target = [u8];
1173
1174 fn deref(&self) -> &[u8] {
1175 unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len) }
1176 }
1177}
1178
1179impl std::ops::DerefMut for MutableBuffer {
1180 fn deref_mut(&mut self) -> &mut [u8] {
1181 unsafe { std::slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
1182 }
1183}
1184
1185impl AsRef<[u8]> for &MutableBuffer {
1186 fn as_ref(&self) -> &[u8] {
1187 self.as_slice()
1188 }
1189}
1190
1191impl Drop for MutableBuffer {
1192 fn drop(&mut self) {
1193 if self.layout.size() != 0 {
1194 unsafe { std::alloc::dealloc(self.data.as_ptr().cast(), self.layout) };
1196 }
1197 }
1198}
1199
1200impl PartialEq for MutableBuffer {
1201 fn eq(&self, other: &MutableBuffer) -> bool {
1202 if self.len != other.len {
1203 return false;
1204 }
1205 if self.layout != other.layout {
1206 return false;
1207 }
1208 self.as_slice() == other.as_slice()
1209 }
1210}
1211
1212unsafe impl Sync for MutableBuffer {}
1213unsafe impl Send for MutableBuffer {}
1214
1215struct SetLenOnDrop<'a> {
1216 len: &'a mut usize,
1217 local_len: usize,
1218}
1219
1220impl<'a> SetLenOnDrop<'a> {
1221 #[inline]
1222 fn new(len: &'a mut usize) -> Self {
1223 SetLenOnDrop {
1224 local_len: *len,
1225 len,
1226 }
1227 }
1228}
1229
1230impl Drop for SetLenOnDrop<'_> {
1231 #[inline]
1232 fn drop(&mut self) {
1233 *self.len = self.local_len;
1234 }
1235}
1236
1237impl std::iter::FromIterator<bool> for MutableBuffer {
1239 fn from_iter<I>(iter: I) -> Self
1240 where
1241 I: IntoIterator<Item = bool>,
1242 {
1243 let mut iterator = iter.into_iter();
1244 let mut result = {
1245 let byte_capacity: usize = iterator.size_hint().0.saturating_add(7) / 8;
1246 MutableBuffer::new(byte_capacity)
1247 };
1248
1249 loop {
1250 let mut exhausted = false;
1251 let mut byte_accum: u8 = 0;
1252 let mut mask: u8 = 1;
1253
1254 while mask != 0 {
1256 if let Some(value) = iterator.next() {
1257 byte_accum |= match value {
1258 true => mask,
1259 false => 0,
1260 };
1261 mask <<= 1;
1262 } else {
1263 exhausted = true;
1264 break;
1265 }
1266 }
1267
1268 if exhausted && mask == 1 {
1270 break;
1271 }
1272
1273 if result.len() == result.capacity() {
1275 let additional_byte_capacity = 1usize.saturating_add(
1277 iterator.size_hint().0.saturating_add(7) / 8, );
1279 result.reserve(additional_byte_capacity)
1280 }
1281
1282 unsafe { result.push_unchecked(byte_accum) };
1284 if exhausted {
1285 break;
1286 }
1287 }
1288 result
1289 }
1290}
1291
1292impl<T: ArrowNativeType> std::iter::FromIterator<T> for MutableBuffer {
1293 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1294 let mut buffer = Self::default();
1295 buffer.extend_from_iter(iter.into_iter());
1296 buffer
1297 }
1298}
1299
1300#[cfg(test)]
1301mod tests {
1302 use super::*;
1303
1304 #[test]
1305 fn test_mutable_new() {
1306 let buf = MutableBuffer::new(63);
1307 assert_eq!(64, buf.capacity());
1308 assert_eq!(0, buf.len());
1309 assert!(buf.is_empty());
1310 }
1311
1312 #[test]
1313 fn test_mutable_default() {
1314 let buf = MutableBuffer::default();
1315 assert_eq!(0, buf.capacity());
1316 assert_eq!(0, buf.len());
1317 assert!(buf.is_empty());
1318
1319 let mut buf = MutableBuffer::default();
1320 buf.extend_from_slice(b"hello");
1321 assert_eq!(5, buf.len());
1322 assert_eq!(b"hello", buf.as_slice());
1323 }
1324
1325 #[test]
1326 fn test_mutable_extend_from_slice() {
1327 let mut buf = MutableBuffer::new(100);
1328 buf.extend_from_slice(b"hello");
1329 assert_eq!(5, buf.len());
1330 assert_eq!(b"hello", buf.as_slice());
1331
1332 buf.extend_from_slice(b" world");
1333 assert_eq!(11, buf.len());
1334 assert_eq!(b"hello world", buf.as_slice());
1335
1336 buf.clear();
1337 assert_eq!(0, buf.len());
1338 buf.extend_from_slice(b"hello arrow");
1339 assert_eq!(11, buf.len());
1340 assert_eq!(b"hello arrow", buf.as_slice());
1341 }
1342
1343 #[test]
1344 fn mutable_extend_from_iter() {
1345 let mut buf = MutableBuffer::new(0);
1346 buf.extend(vec![1u32, 2]);
1347 assert_eq!(8, buf.len());
1348 assert_eq!(&[1u8, 0, 0, 0, 2, 0, 0, 0], buf.as_slice());
1349
1350 buf.extend(vec![3u32, 4]);
1351 assert_eq!(16, buf.len());
1352 assert_eq!(
1353 &[1u8, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0],
1354 buf.as_slice()
1355 );
1356 }
1357
1358 #[test]
1359 fn mutable_extend_from_iter_unaligned_u64() {
1360 let mut buf = MutableBuffer::new(16);
1361 buf.push(1_u8);
1362 buf.extend([1_u64]);
1363 assert_eq!(9, buf.len());
1364 assert_eq!(&[1u8, 1u8, 0, 0, 0, 0, 0, 0, 0], buf.as_slice());
1365 }
1366
1367 #[test]
1368 fn mutable_extend_from_slice_unaligned_u64() {
1369 let mut buf = MutableBuffer::new(16);
1370 buf.extend_from_slice(&[1_u8]);
1371 buf.extend_from_slice(&[1_u64]);
1372 assert_eq!(9, buf.len());
1373 assert_eq!(&[1u8, 1u8, 0, 0, 0, 0, 0, 0, 0], buf.as_slice());
1374 }
1375
1376 #[test]
1377 fn mutable_push_unaligned_u64() {
1378 let mut buf = MutableBuffer::new(16);
1379 buf.push(1_u8);
1380 buf.push(1_u64);
1381 assert_eq!(9, buf.len());
1382 assert_eq!(&[1u8, 1u8, 0, 0, 0, 0, 0, 0, 0], buf.as_slice());
1383 }
1384
1385 #[test]
1386 fn mutable_push_unchecked_unaligned_u64() {
1387 let mut buf = MutableBuffer::new(16);
1388 unsafe {
1389 buf.push_unchecked(1_u8);
1390 buf.push_unchecked(1_u64);
1391 }
1392 assert_eq!(9, buf.len());
1393 assert_eq!(&[1u8, 1u8, 0, 0, 0, 0, 0, 0, 0], buf.as_slice());
1394 }
1395
1396 #[test]
1397 fn test_from_trusted_len_iter() {
1398 let iter = vec![1u32, 2].into_iter();
1399 let buf = unsafe { MutableBuffer::from_trusted_len_iter(iter) };
1400 assert_eq!(8, buf.len());
1401 assert_eq!(&[1u8, 0, 0, 0, 2, 0, 0, 0], buf.as_slice());
1402 }
1403
1404 #[test]
1405 fn test_mutable_reserve() {
1406 let mut buf = MutableBuffer::new(1);
1407 assert_eq!(64, buf.capacity());
1408
1409 buf.reserve(10);
1411 assert_eq!(64, buf.capacity());
1412
1413 buf.reserve(80);
1414 assert_eq!(128, buf.capacity());
1415
1416 buf.reserve(129);
1417 assert_eq!(256, buf.capacity());
1418 }
1419
1420 #[test]
1421 fn test_mutable_resize() {
1422 let mut buf = MutableBuffer::new(1);
1423 assert_eq!(64, buf.capacity());
1424 assert_eq!(0, buf.len());
1425
1426 buf.resize(20, 0);
1427 assert_eq!(64, buf.capacity());
1428 assert_eq!(20, buf.len());
1429
1430 buf.resize(10, 0);
1431 assert_eq!(64, buf.capacity());
1432 assert_eq!(10, buf.len());
1433
1434 buf.resize(100, 0);
1435 assert_eq!(128, buf.capacity());
1436 assert_eq!(100, buf.len());
1437
1438 buf.resize(30, 0);
1439 assert_eq!(128, buf.capacity());
1440 assert_eq!(30, buf.len());
1441
1442 buf.resize(0, 0);
1443 assert_eq!(128, buf.capacity());
1444 assert_eq!(0, buf.len());
1445 }
1446
1447 #[test]
1448 fn test_mutable_into() {
1449 let mut buf = MutableBuffer::new(1);
1450 buf.extend_from_slice(b"aaaa bbbb cccc dddd");
1451 assert_eq!(19, buf.len());
1452 assert_eq!(64, buf.capacity());
1453 assert_eq!(b"aaaa bbbb cccc dddd", buf.as_slice());
1454
1455 let immutable_buf: Buffer = buf.into();
1456 assert_eq!(19, immutable_buf.len());
1457 assert_eq!(64, immutable_buf.capacity());
1458 assert_eq!(b"aaaa bbbb cccc dddd", immutable_buf.as_slice());
1459 }
1460
1461 #[test]
1462 fn test_mutable_equal() {
1463 let mut buf = MutableBuffer::new(1);
1464 let mut buf2 = MutableBuffer::new(1);
1465
1466 buf.extend_from_slice(&[0xaa]);
1467 buf2.extend_from_slice(&[0xaa, 0xbb]);
1468 assert!(buf != buf2);
1469
1470 buf.extend_from_slice(&[0xbb]);
1471 assert_eq!(buf, buf2);
1472
1473 buf2.reserve(65);
1474 assert!(buf != buf2);
1475 }
1476
1477 #[test]
1478 fn test_mutable_shrink_to_fit() {
1479 let mut buffer = MutableBuffer::new(128);
1480 assert_eq!(buffer.capacity(), 128);
1481 buffer.push(1);
1482 buffer.push(2);
1483
1484 buffer.shrink_to_fit();
1485 assert!(buffer.capacity() >= 64 && buffer.capacity() < 128);
1486 }
1487
1488 #[test]
1489 fn test_mutable_set_null_bits() {
1490 let mut buffer = MutableBuffer::new(8).with_bitset(8, true);
1491
1492 for i in 0..=buffer.capacity() {
1493 buffer.set_null_bits(i, 0);
1494 assert_eq!(buffer[..8], [255; 8][..]);
1495 }
1496
1497 buffer.set_null_bits(1, 4);
1498 assert_eq!(buffer[..8], [255, 0, 0, 0, 0, 255, 255, 255][..]);
1499 }
1500
1501 #[test]
1502 #[should_panic = "out of bounds for buffer of length"]
1503 fn test_mutable_set_null_bits_oob() {
1504 let mut buffer = MutableBuffer::new(64);
1505 buffer.set_null_bits(1, buffer.capacity());
1506 }
1507
1508 #[test]
1509 #[should_panic = "out of bounds for buffer of length"]
1510 fn test_mutable_set_null_bits_oob_by_overflow() {
1511 let mut buffer = MutableBuffer::new(0);
1512 buffer.set_null_bits(1, usize::MAX);
1513 }
1514
1515 #[test]
1516 fn from_iter() {
1517 let buffer = [1u16, 2, 3, 4].into_iter().collect::<MutableBuffer>();
1518 assert_eq!(buffer.len(), 4 * mem::size_of::<u16>());
1519 assert_eq!(buffer.as_slice(), &[1, 0, 2, 0, 3, 0, 4, 0]);
1520 }
1521
1522 #[test]
1523 #[should_panic(expected = "invalid allocation layout for requested capacity")]
1524 fn test_with_capacity_panics_above_max_capacity() {
1525 let max_capacity = isize::MAX as usize - (isize::MAX as usize % ALIGNMENT);
1526 let _ = MutableBuffer::with_capacity(max_capacity + 1);
1527 }
1528
1529 #[cfg(feature = "pool")]
1530 mod pool_tests {
1531 use super::*;
1532 use crate::pool::{MemoryPool, TrackingMemoryPool};
1533
1534 #[test]
1535 fn test_reallocate_with_pool() {
1536 let pool = TrackingMemoryPool::default();
1537 let mut buffer = MutableBuffer::with_capacity(100);
1538 buffer.claim(&pool);
1539
1540 assert_eq!(buffer.capacity(), 128);
1542 assert_eq!(pool.used(), 128);
1543
1544 buffer.try_reallocate(200).unwrap();
1546
1547 assert_eq!(buffer.capacity(), 200);
1549 assert_eq!(pool.used(), 200);
1550
1551 buffer.try_reallocate(50).unwrap();
1553
1554 assert_eq!(buffer.capacity(), 50);
1556 assert_eq!(pool.used(), 50);
1557 }
1558
1559 #[test]
1560 fn test_truncate_with_pool() {
1561 let pool = TrackingMemoryPool::default();
1562 let mut buffer = MutableBuffer::with_capacity(100);
1563
1564 buffer.resize(80, 1);
1566 assert_eq!(buffer.len(), 80);
1567
1568 buffer.claim(&pool);
1569 assert_eq!(pool.used(), 128);
1570
1571 buffer.truncate(40);
1573 assert_eq!(buffer.len(), 40);
1574 assert_eq!(pool.used(), 40);
1575
1576 buffer.clear();
1578 assert_eq!(buffer.len(), 0);
1579 assert_eq!(pool.used(), 0);
1580 }
1581
1582 #[test]
1583 fn test_resize_with_pool() {
1584 let pool = TrackingMemoryPool::default();
1585 let mut buffer = MutableBuffer::with_capacity(100);
1586 buffer.claim(&pool);
1587
1588 assert_eq!(buffer.len(), 0);
1590 assert_eq!(pool.used(), 128);
1591
1592 buffer.resize(50, 1);
1594 assert_eq!(buffer.len(), 50);
1595 assert_eq!(pool.used(), 50);
1596
1597 buffer.resize(150, 1);
1599 assert_eq!(buffer.len(), 150);
1600 assert_eq!(buffer.capacity(), 256);
1601 assert_eq!(pool.used(), 150);
1602
1603 buffer.resize(30, 1);
1605 assert_eq!(buffer.len(), 30);
1606 assert_eq!(pool.used(), 30);
1607 }
1608
1609 #[test]
1610 fn test_buffer_lifecycle_with_pool() {
1611 let pool = TrackingMemoryPool::default();
1612
1613 let mut mutable = MutableBuffer::with_capacity(100);
1615 mutable.resize(80, 1);
1616 mutable.claim(&pool);
1617
1618 assert_eq!(pool.used(), 128);
1620
1621 let buffer = mutable.into_buffer();
1623
1624 assert_eq!(pool.used(), 128);
1626
1627 drop(buffer);
1629 assert_eq!(pool.used(), 0);
1630 }
1631 }
1632
1633 fn create_expected_repeated_slice<T: ArrowNativeType>(
1634 slice_to_repeat: &[T],
1635 repeat_count: usize,
1636 ) -> Buffer {
1637 let mut expected = MutableBuffer::new(size_of_val(slice_to_repeat) * repeat_count);
1638 for _ in 0..repeat_count {
1639 expected.extend_from_slice(slice_to_repeat);
1641 }
1642 expected.into()
1643 }
1644
1645 fn test_repeat_count<T: ArrowNativeType + PartialEq + std::fmt::Debug>(
1647 repeat_count: usize,
1648 test_data: &[T],
1649 ) {
1650 let mut buffer = MutableBuffer::new(0);
1651 buffer.repeat_slice_n_times(test_data, repeat_count);
1652
1653 let expected = create_expected_repeated_slice(test_data, repeat_count);
1654 let result: Buffer = buffer.into();
1655
1656 assert_eq!(
1657 result,
1658 expected,
1659 "Failed for repeat_count={}, slice_len={}",
1660 repeat_count,
1661 test_data.len()
1662 );
1663 }
1664
1665 #[test]
1666 fn test_repeat_slice_count_edge_cases() {
1667 test_repeat_count(100, &[] as &[i32]);
1669
1670 test_repeat_count(0, &[1i32, 2, 3]);
1672 }
1673
1674 #[test]
1675 #[should_panic(expected = "buffer length overflow")]
1676 fn test_repeat_slice_count_multiply_overflow() {
1677 let mut buffer = MutableBuffer::new(0);
1678 buffer.repeat_slice_n_times(&[0_u64], usize::MAX / mem::size_of::<u64>() + 1);
1679 }
1680
1681 #[test]
1682 #[should_panic(expected = "buffer length overflow")]
1683 fn test_repeat_slice_count_len_overflow() {
1684 let mut buffer = MutableBuffer::new(0);
1685 buffer.push(0_u8);
1686 buffer.repeat_slice_n_times(&[0_u8], usize::MAX);
1687 }
1688
1689 #[test]
1690 fn test_small_repeats_counts() {
1691 let data = &[1u8, 2, 3, 4, 5];
1693
1694 for _ in 1..=10 {
1695 test_repeat_count(2, data);
1696 }
1697 }
1698
1699 #[test]
1700 fn test_different_size_of_i32_repeat_slice() {
1701 let data: &[i32] = &[1, 2, 3];
1702 let data_with_single_item: &[i32] = &[42];
1703
1704 for data in &[data, data_with_single_item] {
1705 for item in 1..=9 {
1706 let base_repeat_count = 2_usize.pow(item);
1707 test_repeat_count(base_repeat_count - 1, data);
1708 test_repeat_count(base_repeat_count, data);
1709 test_repeat_count(base_repeat_count + 1, data);
1710 }
1711 }
1712 }
1713
1714 #[test]
1715 fn test_different_size_of_u8_repeat_slice() {
1716 let data: &[u8] = &[1, 2, 3];
1717 let data_with_single_item: &[u8] = &[10];
1718
1719 for data in &[data, data_with_single_item] {
1720 for item in 1..=9 {
1721 let base_repeat_count = 2_usize.pow(item);
1722 test_repeat_count(base_repeat_count - 1, data);
1723 test_repeat_count(base_repeat_count, data);
1724 test_repeat_count(base_repeat_count + 1, data);
1725 }
1726 }
1727 }
1728
1729 #[test]
1730 fn test_different_size_of_u16_repeat_slice() {
1731 let data: &[u16] = &[1, 2, 3];
1732 let data_with_single_item: &[u16] = &[10];
1733
1734 for data in &[data, data_with_single_item] {
1735 for item in 1..=9 {
1736 let base_repeat_count = 2_usize.pow(item);
1737 test_repeat_count(base_repeat_count - 1, data);
1738 test_repeat_count(base_repeat_count, data);
1739 test_repeat_count(base_repeat_count + 1, data);
1740 }
1741 }
1742 }
1743
1744 #[test]
1745 fn test_various_slice_lengths() {
1746 let repeat_count = 37; test_repeat_count(repeat_count, &[42i32]);
1751
1752 test_repeat_count(repeat_count, &[1i32, 2]);
1754 test_repeat_count(repeat_count, &[1i32, 2, 3]);
1755 test_repeat_count(repeat_count, &[1i32, 2, 3, 4]);
1756 test_repeat_count(repeat_count, &[1i32, 2, 3, 4, 5]);
1757
1758 let data_10: Vec<i32> = (0..10).collect();
1760 test_repeat_count(repeat_count, &data_10);
1761
1762 let data_100: Vec<i32> = (0..100).collect();
1763 test_repeat_count(repeat_count, &data_100);
1764
1765 let data_1000: Vec<i32> = (0..1000).collect();
1766 test_repeat_count(repeat_count, &data_1000);
1767 }
1768
1769 #[test]
1770 #[should_panic(expected = "invalid allocation layout for requested capacity")]
1771 fn test_mutable_new_capacity_overflow() {
1772 let _ = MutableBuffer::new(usize::MAX - 10);
1774 }
1775
1776 #[test]
1777 #[should_panic(expected = "buffer length overflow")]
1778 fn test_mutable_reserve_overflow() {
1779 let mut buf = MutableBuffer::new(1);
1781 buf.push(1u8);
1782 buf.reserve(usize::MAX);
1783 }
1784}