Skip to main content

arrow_buffer/buffer/
immutable.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::alloc::Layout;
19use std::fmt::Debug;
20use std::ptr::NonNull;
21use std::sync::Arc;
22
23use crate::BufferBuilder;
24use crate::alloc::{Allocation, Deallocation};
25use crate::util::bit_chunk_iterator::{BitChunks, UnalignedBitChunk};
26use crate::{bit_util, bytes::Bytes, native::ArrowNativeType};
27
28#[cfg(feature = "pool")]
29use crate::pool::MemoryPool;
30
31use super::{MutableBuffer, ScalarBuffer};
32
33/// A contiguous memory region that can be shared with other buffers and across
34/// thread boundaries that stores Arrow data.
35///
36/// `Buffer`s can be sliced and cloned without copying the underlying data and can
37/// be created from memory allocated by non-Rust sources such as C/C++.
38///
39/// # Example: Create a `Buffer` from a `Vec` (without copying)
40/// ```
41/// # use arrow_buffer::Buffer;
42/// let vec: Vec<u32> = vec![1, 2, 3];
43/// let buffer = Buffer::from(vec);
44/// ```
45///
46/// # Example: Convert a `Buffer` to a `Vec` (without copying)
47///
48/// Use [`Self::into_vec`] to convert a `Buffer` back into a `Vec` if there are
49/// no other references and the types are aligned correctly.
50/// ```
51/// # use arrow_buffer::Buffer;
52/// # let vec: Vec<u32> = vec![1, 2, 3];
53/// # let buffer = Buffer::from(vec);
54/// // convert the buffer back into a Vec of u32
55/// // note this will fail if the buffer is shared or not aligned correctly
56/// let vec: Vec<u32> = buffer.into_vec().unwrap();
57/// ```
58///
59/// # Example: Create a `Buffer` from a [`bytes::Bytes`] (without copying)
60///
61/// [`bytes::Bytes`] is a common type in the Rust ecosystem for shared memory
62/// regions. You can create a buffer from a `Bytes` instance using the `From`
63/// implementation, also without copying.
64///
65/// ```
66/// # use arrow_buffer::Buffer;
67/// let bytes = bytes::Bytes::from("hello");
68/// let buffer = Buffer::from(bytes);
69///```
70#[derive(Clone, Debug)]
71pub struct Buffer {
72    /// the internal byte buffer.
73    data: Arc<Bytes>,
74
75    /// Pointer into `data` valid
76    ///
77    /// We store a pointer instead of an offset to avoid pointer arithmetic
78    /// which causes LLVM to fail to vectorise code correctly
79    ptr: *const u8,
80
81    /// Byte length of the buffer.
82    ///
83    /// Must be less than or equal to `data.len()`
84    length: usize,
85}
86
87impl Default for Buffer {
88    #[inline]
89    fn default() -> Self {
90        MutableBuffer::default().into()
91    }
92}
93
94impl PartialEq for Buffer {
95    fn eq(&self, other: &Self) -> bool {
96        self.as_slice().eq(other.as_slice())
97    }
98}
99
100impl Eq for Buffer {}
101
102unsafe impl Send for Buffer where Bytes: Send {}
103unsafe impl Sync for Buffer where Bytes: Sync {}
104
105impl Buffer {
106    /// Create a new Buffer from a (internal) `Bytes`
107    ///
108    /// NOTE despite the same name, `Bytes` is an internal struct in arrow-rs
109    /// and is different than [`bytes::Bytes`].
110    ///
111    /// See examples on [`Buffer`] for ways to create a buffer from a [`bytes::Bytes`].
112    #[deprecated(since = "54.1.0", note = "Use Buffer::from instead")]
113    pub fn from_bytes(bytes: Bytes) -> Self {
114        Self::from(bytes)
115    }
116
117    /// Returns the offset, in bytes, of `Self::ptr` to `Self::data`
118    ///
119    /// self.ptr and self.data can be different after slicing or advancing the buffer.
120    pub fn ptr_offset(&self) -> usize {
121        // Safety: `ptr` is always in bounds of `data`.
122        unsafe { self.ptr.offset_from(self.data.ptr().as_ptr()) as usize }
123    }
124
125    /// Returns the pointer to the start of the buffer without the offset.
126    pub fn data_ptr(&self) -> NonNull<u8> {
127        self.data.ptr()
128    }
129
130    /// Returns the number of strong references to the buffer.
131    ///
132    /// This method is safe but if the buffer is shared across multiple threads
133    /// the underlying value could change between calling this method and using
134    /// the result.
135    pub fn strong_count(&self) -> usize {
136        Arc::strong_count(&self.data)
137    }
138
139    /// Create a [`Buffer`] from the provided [`Vec`] without copying
140    #[inline]
141    pub fn from_vec<T: ArrowNativeType>(vec: Vec<T>) -> Self {
142        MutableBuffer::from(vec).into()
143    }
144
145    /// Initializes a [Buffer] from a slice of items.
146    pub fn from_slice_ref<U: ArrowNativeType, T: AsRef<[U]>>(items: T) -> Self {
147        let slice = items.as_ref();
148        let capacity = std::mem::size_of_val(slice);
149        let mut buffer = MutableBuffer::with_capacity(capacity);
150        buffer.extend_from_slice(slice);
151        buffer.into()
152    }
153
154    /// Creates a buffer from an existing memory region.
155    ///
156    /// Ownership of the memory is tracked via reference counting
157    /// and the memory will be freed using the `drop` method of
158    /// [crate::alloc::Allocation] when the reference count reaches zero.
159    ///
160    /// # Arguments
161    ///
162    /// * `ptr` - Pointer to raw parts
163    /// * `len` - Length of raw parts in **bytes**
164    /// * `owner` - A [crate::alloc::Allocation] which is responsible for freeing that data
165    ///
166    /// # Safety
167    ///
168    /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` bytes
169    pub unsafe fn from_custom_allocation(
170        ptr: NonNull<u8>,
171        len: usize,
172        owner: Arc<dyn Allocation>,
173    ) -> Self {
174        unsafe { Buffer::build_with_arguments(ptr, len, Deallocation::Custom(owner, len)) }
175    }
176
177    /// Auxiliary method to create a new Buffer
178    unsafe fn build_with_arguments(
179        ptr: NonNull<u8>,
180        len: usize,
181        deallocation: Deallocation,
182    ) -> Self {
183        let bytes = unsafe { Bytes::new(ptr, len, deallocation) };
184        let ptr = bytes.as_ptr();
185        Buffer {
186            ptr,
187            data: Arc::new(bytes),
188            length: len,
189        }
190    }
191
192    /// Returns the number of bytes in the buffer
193    #[inline]
194    pub fn len(&self) -> usize {
195        self.length
196    }
197
198    /// Returns the capacity of this buffer.
199    /// For externally owned buffers, this returns zero
200    #[inline]
201    pub fn capacity(&self) -> usize {
202        self.data.capacity()
203    }
204
205    /// Tries to shrink the capacity of the buffer as much as possible, freeing unused memory.
206    ///
207    /// If the buffer is shared, this is a no-op.
208    ///
209    /// If the memory was allocated with a custom allocator, this is a no-op.
210    ///
211    /// If the capacity is already less than or equal to the desired capacity, this is a no-op.
212    ///
213    /// The memory region will be reallocated using `std::alloc::realloc`.
214    pub fn shrink_to_fit(&mut self) {
215        let offset = self.ptr_offset();
216        let is_empty = self.is_empty();
217        let desired_capacity = if is_empty {
218            0
219        } else {
220            // For realloc to work, we cannot free the elements before the offset
221            offset + self.len()
222        };
223        if desired_capacity < self.capacity() {
224            if let Some(bytes) = Arc::get_mut(&mut self.data) {
225                bytes
226                    .try_realloc(desired_capacity, |base| {
227                        self.ptr = if is_empty {
228                            base.as_ptr()
229                        } else {
230                            // SAFETY: we kept all elements leading up to the offset
231                            unsafe { base.as_ptr().add(offset) }
232                        };
233                    })
234                    .ok(); // Failure to reallocate is fine; we just failed to free up memory.
235            }
236        }
237    }
238
239    /// Returns true if the buffer is empty.
240    #[inline]
241    pub fn is_empty(&self) -> bool {
242        self.length == 0
243    }
244
245    /// Returns the byte slice stored in this buffer
246    pub fn as_slice(&self) -> &[u8] {
247        unsafe { std::slice::from_raw_parts(self.ptr, self.length) }
248    }
249
250    pub(crate) fn deallocation(&self) -> &Deallocation {
251        self.data.deallocation()
252    }
253
254    /// Returns a new [Buffer] that is a slice of this buffer starting at `offset`.
255    ///
256    /// This function is `O(1)` and does not copy any data, allowing the
257    /// same memory region to be shared between buffers.
258    ///
259    /// # Panics
260    ///
261    /// Panics iff `offset` is larger than `len`.
262    pub fn slice(&self, offset: usize) -> Self {
263        let mut s = self.clone();
264        s.advance(offset);
265        s
266    }
267
268    /// Increases the offset of this buffer by `offset`
269    ///
270    /// # Panics
271    ///
272    /// Panics iff `offset` is larger than `len`.
273    #[inline]
274    pub fn advance(&mut self, offset: usize) {
275        assert!(
276            offset <= self.length,
277            "the offset of the new Buffer cannot exceed the existing length: offset={} length={}",
278            offset,
279            self.length
280        );
281        self.length -= offset;
282        // Safety:
283        // This cannot overflow as
284        // `self.offset + self.length < self.data.len()`
285        // `offset < self.length`
286        self.ptr = unsafe { self.ptr.add(offset) };
287    }
288
289    /// Returns a new [Buffer] that is a slice of this buffer starting at `offset`,
290    /// with `length` bytes.
291    ///
292    /// This function is `O(1)` and does not copy any data, allowing the same
293    /// memory region to be shared between buffers.
294    ///
295    /// # Panics
296    /// Panics iff `(offset + length)` is larger than the existing length.
297    pub fn slice_with_length(&self, offset: usize, length: usize) -> Self {
298        assert!(
299            offset.saturating_add(length) <= self.length,
300            "the offset of the new Buffer cannot exceed the existing length: slice offset={offset} length={length} selflen={}",
301            self.length
302        );
303        // Safety:
304        // offset + length <= self.length
305        let ptr = unsafe { self.ptr.add(offset) };
306        Self {
307            data: self.data.clone(),
308            ptr,
309            length,
310        }
311    }
312
313    /// Returns a pointer to the start of this buffer.
314    ///
315    /// Note that this should be used cautiously, and the returned pointer should not be
316    /// stored anywhere, to avoid dangling pointers.
317    #[inline]
318    pub fn as_ptr(&self) -> *const u8 {
319        self.ptr
320    }
321
322    /// View buffer as a slice of a specific type.
323    ///
324    /// # Panics
325    ///
326    /// This function panics if the underlying buffer is not aligned
327    /// correctly for type `T`.
328    pub fn typed_data<T: ArrowNativeType>(&self) -> &[T] {
329        // SAFETY
330        // ArrowNativeType is trivially transmutable, is sealed to prevent potentially incorrect
331        // implementation outside this crate, and this method checks alignment
332        let (prefix, offsets, suffix) = unsafe { self.as_slice().align_to::<T>() };
333        assert!(prefix.is_empty() && suffix.is_empty());
334        offsets
335    }
336
337    /// Returns a slice of this buffer starting at a certain bit offset.
338    /// If the offset is byte-aligned the returned buffer is a shallow clone,
339    /// otherwise a new buffer is allocated and filled with a copy of the bits in the range.
340    pub fn bit_slice(&self, offset: usize, len: usize) -> Self {
341        if offset % 8 == 0 {
342            return self.slice_with_length(offset / 8, bit_util::ceil(len, 8));
343        }
344
345        let chunks = self.bit_chunks(offset, len);
346
347        let buffer: Vec<u64> = if chunks.remainder_len() > 0 {
348            chunks.iter().chain(Some(chunks.remainder_bits())).collect()
349        } else {
350            chunks.iter().collect()
351        };
352        let mut buffer = Buffer::from_vec(buffer);
353        // Update length to be byte-aligned
354        buffer.length = bit_util::ceil(len, 8);
355        buffer
356    }
357
358    /// Returns a `BitChunks` instance which can be used to iterate over this buffers bits
359    /// in larger chunks and starting at arbitrary bit offsets.
360    /// Note that both `offset` and `length` are measured in bits.
361    pub fn bit_chunks(&self, offset: usize, len: usize) -> BitChunks<'_> {
362        BitChunks::new(self.as_slice(), offset, len)
363    }
364
365    /// Returns the number of 1-bits in this buffer, starting from `offset` with `length` bits
366    /// inspected. Note that both `offset` and `length` are measured in bits.
367    pub fn count_set_bits_offset(&self, offset: usize, len: usize) -> usize {
368        UnalignedBitChunk::new(self.as_slice(), offset, len).count_ones()
369    }
370
371    /// Returns `MutableBuffer` for mutating the buffer if this buffer is not shared or sliced.
372    /// Returns `Err` if this is shared or the [`Self::ptr_offset`] is greater than 0 or its allocation is from an external source or
373    /// it is not allocated with alignment [`ALIGNMENT`]
374    ///
375    /// # Example: Creating a [`MutableBuffer`] from a [`Buffer`]
376    /// ```
377    /// # use arrow_buffer::buffer::{Buffer, MutableBuffer};
378    /// let buffer: Buffer = Buffer::from(&[1u8, 2, 3, 4][..]);
379    /// // Only possible to convert a Buffer into a MutableBuffer if uniquely owned
380    /// // (i.e., there are no other references to it).
381    /// let mut mutable_buffer = match buffer.into_mutable() {
382    ///    Ok(mutable) => mutable,
383    ///    Err(orig_buffer) => {
384    ///      panic!("buffer was not uniquely owned");
385    ///    }
386    /// };
387    /// mutable_buffer.push(5u8);
388    /// let buffer = Buffer::from(mutable_buffer);
389    /// assert_eq!(buffer.as_slice(), &[1u8, 2, 3, 4, 5])
390    /// ```
391    ///
392    /// [`ALIGNMENT`]: crate::alloc::ALIGNMENT
393    pub fn into_mutable(self) -> Result<MutableBuffer, Self> {
394        let ptr = self.ptr;
395        let length = self.length;
396
397        // Disallow converting when the offset is not 0 because we can't start a mutable from offset
398        let res = if self.ptr_offset() > 0 {
399            Err(self.data)
400        } else {
401            Arc::try_unwrap(self.data)
402        };
403
404        res.and_then(|bytes| {
405            // The pointer of underlying buffer should not be offset.
406            assert_eq!(ptr, bytes.ptr().as_ptr());
407            MutableBuffer::from_bytes(bytes).map_err(Arc::new)
408        })
409        .map_err(|bytes| Buffer {
410            data: bytes,
411            ptr,
412            length,
413        })
414        .map(|mut mutable| {
415            // We need to update the length since in case we are converting sliced buffer we need to return MutableBuffer with the same length
416            // SAFETY: this is safe as the length is coming from valid Buffer (this) and it is guaranteed to be less than the underlying data buffer
417            unsafe { mutable.set_len(length) };
418            mutable
419        })
420    }
421
422    /// Converts self into a `Vec`, if possible.
423    ///
424    /// This can be used to reuse / mutate the underlying data.
425    ///
426    /// # Errors
427    ///
428    /// Returns `Err(self)` if
429    /// 1. The buffer does not have the same [`Layout`] as the destination Vec
430    /// 2. The buffer contains a non-zero offset
431    /// 3. The buffer is shared
432    pub fn into_vec<T: ArrowNativeType>(self) -> Result<Vec<T>, Self> {
433        let layout = match self.data.deallocation() {
434            Deallocation::Standard(l) => l,
435            _ => return Err(self), // Custom allocation
436        };
437
438        if self.ptr != self.data.as_ptr() {
439            return Err(self); // Data is offset
440        }
441
442        let v_capacity = layout.size() / std::mem::size_of::<T>();
443        match Layout::array::<T>(v_capacity) {
444            Ok(expected) if layout == &expected => {}
445            _ => return Err(self), // Incorrect layout
446        }
447
448        let length = self.length;
449        let ptr = self.ptr;
450        let v_len = self.length / std::mem::size_of::<T>();
451
452        Arc::try_unwrap(self.data)
453            .map(|bytes| unsafe {
454                let ptr = bytes.ptr().as_ptr() as _;
455                std::mem::forget(bytes);
456                // Safety
457                // Verified that bytes layout matches that of Vec
458                Vec::from_raw_parts(ptr, v_len, v_capacity)
459            })
460            .map_err(|bytes| Buffer {
461                data: bytes,
462                ptr,
463                length,
464            })
465    }
466
467    /// Returns true if this [`Buffer`] is equal to `other`, using pointer comparisons
468    /// to determine buffer equality. This is cheaper than `PartialEq::eq` but may
469    /// return false when the arrays are logically equal
470    #[inline]
471    pub fn ptr_eq(&self, other: &Self) -> bool {
472        self.ptr == other.ptr && self.length == other.length
473    }
474
475    /// Register this [`Buffer`] with the provided [`MemoryPool`]
476    ///
477    /// This claims the memory used by this buffer in the pool, allowing for
478    /// accurate accounting of memory usage. Any prior reservation will be
479    /// released so this works well when the buffer is being shared among
480    /// multiple arrays.
481    #[cfg(feature = "pool")]
482    pub fn claim(&self, pool: &dyn MemoryPool) {
483        self.data.claim(pool)
484    }
485}
486
487/// Note that here we deliberately do not implement
488/// `impl<T: AsRef<[u8]>> From<T> for Buffer`
489/// As it would accept `Buffer::from(vec![...])` that would cause an unexpected copy.
490/// Instead, we ask user to be explicit when copying is occurring, e.g., `Buffer::from(vec![...].to_byte_slice())`.
491/// For zero-copy conversion, user should use `Buffer::from_vec(vec![...])`.
492///
493/// Since we removed impl for `AsRef<u8>`, we added the following three specific implementations to reduce API breakage.
494/// See <https://github.com/apache/arrow-rs/issues/6033> for more discussion on this.
495impl From<&[u8]> for Buffer {
496    fn from(p: &[u8]) -> Self {
497        Self::from_slice_ref(p)
498    }
499}
500
501impl<const N: usize> From<[u8; N]> for Buffer {
502    fn from(p: [u8; N]) -> Self {
503        Self::from_slice_ref(p)
504    }
505}
506
507impl<const N: usize> From<&[u8; N]> for Buffer {
508    fn from(p: &[u8; N]) -> Self {
509        Self::from_slice_ref(p)
510    }
511}
512
513impl<T: ArrowNativeType> From<Vec<T>> for Buffer {
514    fn from(value: Vec<T>) -> Self {
515        Self::from_vec(value)
516    }
517}
518
519impl<T: ArrowNativeType> From<ScalarBuffer<T>> for Buffer {
520    fn from(value: ScalarBuffer<T>) -> Self {
521        value.into_inner()
522    }
523}
524
525/// Convert from internal `Bytes` (not [`bytes::Bytes`]) to `Buffer`
526impl From<Bytes> for Buffer {
527    #[inline]
528    fn from(bytes: Bytes) -> Self {
529        let length = bytes.len();
530        let ptr = bytes.as_ptr();
531        Self {
532            data: Arc::new(bytes),
533            ptr,
534            length,
535        }
536    }
537}
538
539/// Convert from [`bytes::Bytes`], not internal `Bytes` to `Buffer`
540impl From<bytes::Bytes> for Buffer {
541    fn from(bytes: bytes::Bytes) -> Self {
542        let bytes: Bytes = bytes.into();
543        Self::from(bytes)
544    }
545}
546
547/// Create a `Buffer` instance by storing the boolean values into the buffer
548impl FromIterator<bool> for Buffer {
549    fn from_iter<I>(iter: I) -> Self
550    where
551        I: IntoIterator<Item = bool>,
552    {
553        MutableBuffer::from_iter(iter).into()
554    }
555}
556
557impl std::ops::Deref for Buffer {
558    type Target = [u8];
559
560    fn deref(&self) -> &[u8] {
561        unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len()) }
562    }
563}
564
565impl AsRef<[u8]> for &Buffer {
566    fn as_ref(&self) -> &[u8] {
567        self.as_slice()
568    }
569}
570
571impl From<MutableBuffer> for Buffer {
572    #[inline]
573    fn from(buffer: MutableBuffer) -> Self {
574        buffer.into_buffer()
575    }
576}
577
578impl<T: ArrowNativeType> From<BufferBuilder<T>> for Buffer {
579    fn from(mut value: BufferBuilder<T>) -> Self {
580        value.finish()
581    }
582}
583
584impl Buffer {
585    /// Creates a [`Buffer`] from an [`Iterator`] with a trusted (upper) length.
586    ///
587    /// Prefer this to `collect` whenever possible, as it is ~60% faster.
588    ///
589    /// # Example
590    /// ```
591    /// # use arrow_buffer::buffer::Buffer;
592    /// let v = vec![1u32];
593    /// let iter = v.iter().map(|x| x * 2);
594    /// let buffer = unsafe { Buffer::from_trusted_len_iter(iter) };
595    /// assert_eq!(buffer.len(), 4) // u32 has 4 bytes
596    /// ```
597    /// # Safety
598    /// This method assumes that the iterator's size is correct and is undefined behavior
599    /// to use it on an iterator that reports an incorrect length.
600    // This implementation is required for two reasons:
601    // 1. there is no trait `TrustedLen` in stable rust and therefore
602    //    we can't specialize `extend` for `TrustedLen` like `Vec` does.
603    // 2. `from_trusted_len_iter` is faster.
604    #[inline]
605    pub unsafe fn from_trusted_len_iter<T: ArrowNativeType, I: Iterator<Item = T>>(
606        iterator: I,
607    ) -> Self {
608        unsafe { MutableBuffer::from_trusted_len_iter(iterator).into() }
609    }
610
611    /// Creates a [`Buffer`] from an [`Iterator`] with a trusted (upper) length or errors
612    /// if any of the items of the iterator is an error.
613    /// Prefer this to `collect` whenever possible, as it is ~60% faster.
614    /// # Safety
615    /// This method assumes that the iterator's size is correct and is undefined behavior
616    /// to use it on an iterator that reports an incorrect length.
617    #[inline]
618    pub unsafe fn try_from_trusted_len_iter<
619        E,
620        T: ArrowNativeType,
621        I: Iterator<Item = Result<T, E>>,
622    >(
623        iterator: I,
624    ) -> Result<Self, E> {
625        unsafe { Ok(MutableBuffer::try_from_trusted_len_iter(iterator)?.into()) }
626    }
627}
628
629impl<T: ArrowNativeType> FromIterator<T> for Buffer {
630    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
631        let vec = Vec::from_iter(iter);
632        Buffer::from_vec(vec)
633    }
634}
635
636#[cfg(test)]
637mod tests {
638    use crate::i256;
639    use std::panic::{RefUnwindSafe, UnwindSafe};
640    use std::thread;
641
642    use super::*;
643
644    #[test]
645    fn test_buffer_data_equality() {
646        let buf1 = Buffer::from(&[0, 1, 2, 3, 4]);
647        let buf2 = Buffer::from(&[0, 1, 2, 3, 4]);
648        assert_eq!(buf1, buf2);
649
650        // slice with same offset and same length should still preserve equality
651        let buf3 = buf1.slice(2);
652        assert_ne!(buf1, buf3);
653        let buf4 = buf2.slice_with_length(2, 3);
654        assert_eq!(buf3, buf4);
655
656        // Different capacities should still preserve equality
657        let mut buf2 = MutableBuffer::new(65);
658        buf2.extend_from_slice(&[0u8, 1, 2, 3, 4]);
659
660        let buf2 = buf2.into();
661        assert_eq!(buf1, buf2);
662
663        // unequal because of different elements
664        let buf2 = Buffer::from(&[0, 0, 2, 3, 4]);
665        assert_ne!(buf1, buf2);
666
667        // unequal because of different length
668        let buf2 = Buffer::from(&[0, 1, 2, 3]);
669        assert_ne!(buf1, buf2);
670    }
671
672    #[test]
673    fn test_from_raw_parts() {
674        let buf = Buffer::from(&[0, 1, 2, 3, 4]);
675        assert_eq!(5, buf.len());
676        assert!(!buf.as_ptr().is_null());
677        assert_eq!([0, 1, 2, 3, 4], buf.as_slice());
678    }
679
680    #[test]
681    fn test_from_vec() {
682        let buf = Buffer::from(&[0, 1, 2, 3, 4]);
683        assert_eq!(5, buf.len());
684        assert!(!buf.as_ptr().is_null());
685        assert_eq!([0, 1, 2, 3, 4], buf.as_slice());
686    }
687
688    #[test]
689    fn test_copy() {
690        let buf = Buffer::from(&[0, 1, 2, 3, 4]);
691        let buf2 = buf;
692        assert_eq!(5, buf2.len());
693        assert_eq!(64, buf2.capacity());
694        assert!(!buf2.as_ptr().is_null());
695        assert_eq!([0, 1, 2, 3, 4], buf2.as_slice());
696    }
697
698    #[test]
699    fn test_slice() {
700        let buf = Buffer::from(&[2, 4, 6, 8, 10]);
701        let buf2 = buf.slice(2);
702
703        assert_eq!([6, 8, 10], buf2.as_slice());
704        assert_eq!(3, buf2.len());
705        assert_eq!(unsafe { buf.as_ptr().offset(2) }, buf2.as_ptr());
706
707        let buf3 = buf2.slice_with_length(1, 2);
708        assert_eq!([8, 10], buf3.as_slice());
709        assert_eq!(2, buf3.len());
710        assert_eq!(unsafe { buf.as_ptr().offset(3) }, buf3.as_ptr());
711
712        let buf4 = buf.slice(5);
713        let empty_slice: [u8; 0] = [];
714        assert_eq!(empty_slice, buf4.as_slice());
715        assert_eq!(0, buf4.len());
716        assert!(buf4.is_empty());
717        assert_eq!(buf2.slice_with_length(2, 1).as_slice(), &[10]);
718    }
719
720    #[test]
721    fn test_shrink_to_fit() {
722        let original = Buffer::from(&[0, 1, 2, 3, 4, 5, 6, 7]);
723        assert_eq!(original.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7]);
724        assert_eq!(original.capacity(), 64);
725
726        let slice = original.slice_with_length(2, 3);
727        drop(original); // Make sure the buffer isn't shared (or shrink_to_fit won't work)
728        assert_eq!(slice.as_slice(), &[2, 3, 4]);
729        assert_eq!(slice.capacity(), 64);
730
731        let mut shrunk = slice;
732        shrunk.shrink_to_fit();
733        assert_eq!(shrunk.as_slice(), &[2, 3, 4]);
734        assert_eq!(shrunk.capacity(), 5); // shrink_to_fit is allowed to keep the elements before the offset
735
736        // Test that we can handle empty slices:
737        let empty_slice = shrunk.slice_with_length(1, 0);
738        drop(shrunk); // Make sure the buffer isn't shared (or shrink_to_fit won't work)
739        assert_eq!(empty_slice.as_slice(), &[]);
740        assert_eq!(empty_slice.capacity(), 5);
741
742        let mut shrunk_empty = empty_slice;
743        shrunk_empty.shrink_to_fit();
744        assert_eq!(shrunk_empty.as_slice(), &[]);
745        assert_eq!(shrunk_empty.capacity(), 0);
746    }
747
748    #[test]
749    #[should_panic(expected = "the offset of the new Buffer cannot exceed the existing length")]
750    fn test_slice_offset_out_of_bound() {
751        let buf = Buffer::from(&[2, 4, 6, 8, 10]);
752        buf.slice(6);
753    }
754
755    #[test]
756    fn test_access_concurrently() {
757        let buffer = Buffer::from([1, 2, 3, 4, 5]);
758        let buffer2 = buffer.clone();
759        assert_eq!([1, 2, 3, 4, 5], buffer.as_slice());
760
761        let buffer_copy = thread::spawn(move || {
762            // access buffer in another thread.
763            buffer
764        })
765        .join();
766
767        assert!(buffer_copy.is_ok());
768        assert_eq!(buffer2, buffer_copy.ok().unwrap());
769    }
770
771    macro_rules! check_as_typed_data {
772        ($input: expr, $native_t: ty) => {{
773            let buffer = Buffer::from_slice_ref($input);
774            let slice: &[$native_t] = buffer.typed_data::<$native_t>();
775            assert_eq!($input, slice);
776        }};
777    }
778
779    #[test]
780    #[allow(clippy::float_cmp)]
781    fn test_as_typed_data() {
782        check_as_typed_data!(&[1i8, 3i8, 6i8], i8);
783        check_as_typed_data!(&[1u8, 3u8, 6u8], u8);
784        check_as_typed_data!(&[1i16, 3i16, 6i16], i16);
785        check_as_typed_data!(&[1i32, 3i32, 6i32], i32);
786        check_as_typed_data!(&[1i64, 3i64, 6i64], i64);
787        check_as_typed_data!(&[1u16, 3u16, 6u16], u16);
788        check_as_typed_data!(&[1u32, 3u32, 6u32], u32);
789        check_as_typed_data!(&[1u64, 3u64, 6u64], u64);
790        check_as_typed_data!(&[1f32, 3f32, 6f32], f32);
791        check_as_typed_data!(&[1f64, 3f64, 6f64], f64);
792    }
793
794    #[test]
795    fn test_count_bits() {
796        assert_eq!(0, Buffer::from(&[0b00000000]).count_set_bits_offset(0, 8));
797        assert_eq!(8, Buffer::from(&[0b11111111]).count_set_bits_offset(0, 8));
798        assert_eq!(3, Buffer::from(&[0b00001101]).count_set_bits_offset(0, 8));
799        assert_eq!(
800            6,
801            Buffer::from(&[0b01001001, 0b01010010]).count_set_bits_offset(0, 16)
802        );
803        assert_eq!(
804            16,
805            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(0, 16)
806        );
807    }
808
809    #[test]
810    fn test_count_bits_slice() {
811        assert_eq!(
812            0,
813            Buffer::from(&[0b11111111, 0b00000000])
814                .slice(1)
815                .count_set_bits_offset(0, 8)
816        );
817        assert_eq!(
818            8,
819            Buffer::from(&[0b11111111, 0b11111111])
820                .slice_with_length(1, 1)
821                .count_set_bits_offset(0, 8)
822        );
823        assert_eq!(
824            3,
825            Buffer::from(&[0b11111111, 0b11111111, 0b00001101])
826                .slice(2)
827                .count_set_bits_offset(0, 8)
828        );
829        assert_eq!(
830            6,
831            Buffer::from(&[0b11111111, 0b01001001, 0b01010010])
832                .slice_with_length(1, 2)
833                .count_set_bits_offset(0, 16)
834        );
835        assert_eq!(
836            16,
837            Buffer::from(&[0b11111111, 0b11111111, 0b11111111, 0b11111111])
838                .slice(2)
839                .count_set_bits_offset(0, 16)
840        );
841    }
842
843    #[test]
844    fn test_count_bits_offset_slice() {
845        assert_eq!(8, Buffer::from(&[0b11111111]).count_set_bits_offset(0, 8));
846        assert_eq!(3, Buffer::from(&[0b11111111]).count_set_bits_offset(0, 3));
847        assert_eq!(5, Buffer::from(&[0b11111111]).count_set_bits_offset(3, 5));
848        assert_eq!(1, Buffer::from(&[0b11111111]).count_set_bits_offset(3, 1));
849        assert_eq!(0, Buffer::from(&[0b11111111]).count_set_bits_offset(8, 0));
850        assert_eq!(2, Buffer::from(&[0b01010101]).count_set_bits_offset(0, 3));
851        assert_eq!(
852            16,
853            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(0, 16)
854        );
855        assert_eq!(
856            10,
857            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(0, 10)
858        );
859        assert_eq!(
860            10,
861            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(3, 10)
862        );
863        assert_eq!(
864            8,
865            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(8, 8)
866        );
867        assert_eq!(
868            5,
869            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(11, 5)
870        );
871        assert_eq!(
872            0,
873            Buffer::from(&[0b11111111, 0b11111111]).count_set_bits_offset(16, 0)
874        );
875        assert_eq!(
876            2,
877            Buffer::from(&[0b01101101, 0b10101010]).count_set_bits_offset(7, 5)
878        );
879        assert_eq!(
880            4,
881            Buffer::from(&[0b01101101, 0b10101010]).count_set_bits_offset(7, 9)
882        );
883    }
884
885    #[test]
886    fn test_unwind_safe() {
887        fn assert_unwind_safe<T: RefUnwindSafe + UnwindSafe>() {}
888        assert_unwind_safe::<Buffer>()
889    }
890
891    #[test]
892    fn test_from_foreign_vec() {
893        let mut vector = vec![1_i32, 2, 3, 4, 5];
894        let buffer = unsafe {
895            Buffer::from_custom_allocation(
896                NonNull::new_unchecked(vector.as_mut_ptr() as *mut u8),
897                vector.len() * std::mem::size_of::<i32>(),
898                Arc::new(vector),
899            )
900        };
901
902        let slice = buffer.typed_data::<i32>();
903        assert_eq!(slice, &[1, 2, 3, 4, 5]);
904
905        let buffer = buffer.slice(std::mem::size_of::<i32>());
906
907        let slice = buffer.typed_data::<i32>();
908        assert_eq!(slice, &[2, 3, 4, 5]);
909    }
910
911    #[test]
912    #[should_panic(expected = "the offset of the new Buffer cannot exceed the existing length")]
913    fn slice_overflow() {
914        let buffer = Buffer::from(MutableBuffer::from_len_zeroed(12));
915        buffer.slice_with_length(2, usize::MAX);
916    }
917
918    #[test]
919    fn test_vec_interop() {
920        // Test empty vec
921        let a: Vec<i128> = Vec::new();
922        let b = Buffer::from_vec(a);
923        b.into_vec::<i128>().unwrap();
924
925        // Test vec with capacity
926        let a: Vec<i128> = Vec::with_capacity(20);
927        let b = Buffer::from_vec(a);
928        let back = b.into_vec::<i128>().unwrap();
929        assert_eq!(back.len(), 0);
930        assert_eq!(back.capacity(), 20);
931
932        // Test vec with values
933        let mut a: Vec<i128> = Vec::with_capacity(3);
934        a.extend_from_slice(&[1, 2, 3]);
935        let b = Buffer::from_vec(a);
936        let back = b.into_vec::<i128>().unwrap();
937        assert_eq!(back.len(), 3);
938        assert_eq!(back.capacity(), 3);
939
940        // Test vec with values and spare capacity
941        let mut a: Vec<i128> = Vec::with_capacity(20);
942        a.extend_from_slice(&[1, 4, 7, 8, 9, 3, 6]);
943        let b = Buffer::from_vec(a);
944        let back = b.into_vec::<i128>().unwrap();
945        assert_eq!(back.len(), 7);
946        assert_eq!(back.capacity(), 20);
947
948        // Test incorrect alignment
949        let a: Vec<i128> = Vec::new();
950        let b = Buffer::from_vec(a);
951        let b = b.into_vec::<i32>().unwrap_err();
952        b.into_vec::<i8>().unwrap_err();
953
954        // Test convert between types with same alignment
955        // This is an implementation quirk, but isn't harmful
956        // as ArrowNativeType are trivially transmutable
957        let a: Vec<i64> = vec![1, 2, 3, 4];
958        let b = Buffer::from_vec(a);
959        let back = b.into_vec::<u64>().unwrap();
960        assert_eq!(back.len(), 4);
961        assert_eq!(back.capacity(), 4);
962
963        // i256 has the same layout as i128 so this is valid
964        let mut b: Vec<i128> = Vec::with_capacity(4);
965        b.extend_from_slice(&[1, 2, 3, 4]);
966        let b = Buffer::from_vec(b);
967        let back = b.into_vec::<i256>().unwrap();
968        assert_eq!(back.len(), 2);
969        assert_eq!(back.capacity(), 2);
970
971        // Invalid layout
972        let b: Vec<i128> = vec![1, 2, 3];
973        let b = Buffer::from_vec(b);
974        b.into_vec::<i256>().unwrap_err();
975
976        // Invalid layout
977        let mut b: Vec<i128> = Vec::with_capacity(5);
978        b.extend_from_slice(&[1, 2, 3, 4]);
979        let b = Buffer::from_vec(b);
980        b.into_vec::<i256>().unwrap_err();
981
982        // Truncates length
983        // This is an implementation quirk, but isn't harmful
984        let mut b: Vec<i128> = Vec::with_capacity(4);
985        b.extend_from_slice(&[1, 2, 3]);
986        let b = Buffer::from_vec(b);
987        let back = b.into_vec::<i256>().unwrap();
988        assert_eq!(back.len(), 1);
989        assert_eq!(back.capacity(), 2);
990
991        // Cannot use aligned allocation
992        let b = Buffer::from(MutableBuffer::new(10));
993        let b = b.into_vec::<u8>().unwrap_err();
994        b.into_vec::<u64>().unwrap_err();
995
996        // Test slicing
997        let mut a: Vec<i128> = Vec::with_capacity(20);
998        a.extend_from_slice(&[1, 4, 7, 8, 9, 3, 6]);
999        let b = Buffer::from_vec(a);
1000        let slice = b.slice_with_length(0, 64);
1001
1002        // Shared reference fails
1003        let slice = slice.into_vec::<i128>().unwrap_err();
1004        drop(b);
1005
1006        // Succeeds as no outstanding shared reference
1007        let back = slice.into_vec::<i128>().unwrap();
1008        assert_eq!(&back, &[1, 4, 7, 8]);
1009        assert_eq!(back.capacity(), 20);
1010
1011        // Slicing by non-multiple length truncates
1012        let mut a: Vec<i128> = Vec::with_capacity(8);
1013        a.extend_from_slice(&[1, 4, 7, 3]);
1014
1015        let b = Buffer::from_vec(a);
1016        let slice = b.slice_with_length(0, 34);
1017        drop(b);
1018
1019        let back = slice.into_vec::<i128>().unwrap();
1020        assert_eq!(&back, &[1, 4]);
1021        assert_eq!(back.capacity(), 8);
1022
1023        // Offset prevents conversion
1024        let a: Vec<u32> = vec![1, 3, 4, 6];
1025        let b = Buffer::from_vec(a).slice(2);
1026        b.into_vec::<u32>().unwrap_err();
1027
1028        let b = MutableBuffer::new(16).into_buffer();
1029        let b = b.into_vec::<u8>().unwrap_err(); // Invalid layout
1030        let b = b.into_vec::<u32>().unwrap_err(); // Invalid layout
1031        b.into_mutable().unwrap();
1032
1033        let b = Buffer::from_vec(vec![1_u32, 3, 5]);
1034        let b = b.into_mutable().unwrap();
1035        let b = Buffer::from(b);
1036        let b = b.into_vec::<u32>().unwrap();
1037        assert_eq!(b, &[1, 3, 5]);
1038    }
1039
1040    #[test]
1041    #[should_panic(expected = "capacity overflow")]
1042    fn test_from_iter_overflow() {
1043        let iter_len = usize::MAX / std::mem::size_of::<u64>() + 1;
1044        let _ = Buffer::from_iter(std::iter::repeat_n(0_u64, iter_len));
1045    }
1046
1047    #[test]
1048    fn bit_slice_length_preserved() {
1049        // Create a boring buffer
1050        let buf = Buffer::from_iter(std::iter::repeat_n(true, 64));
1051
1052        let assert_preserved = |offset: usize, len: usize| {
1053            let new_buf = buf.bit_slice(offset, len);
1054            assert_eq!(new_buf.len(), bit_util::ceil(len, 8));
1055
1056            // if the offset is not byte-aligned, we have to create a deep copy to a new buffer
1057            // (since the `offset` value inside a Buffer is byte-granular, not bit-granular), so
1058            // checking the offset should always return 0 if so. If the offset IS byte-aligned, we
1059            // want to make sure it doesn't unnecessarily create a deep copy.
1060            if offset % 8 == 0 {
1061                assert_eq!(new_buf.ptr_offset(), offset / 8);
1062            } else {
1063                assert_eq!(new_buf.ptr_offset(), 0);
1064            }
1065        };
1066
1067        // go through every available value for offset
1068        for o in 0..=64 {
1069            // and go through every length that could accompany that offset - we can't have a
1070            // situation where offset + len > 64, because that would go past the end of the buffer,
1071            // so we use the map to ensure it's in range.
1072            for l in (o..=64).map(|l| l - o) {
1073                // and we just want to make sure every one of these keeps its offset and length
1074                // when neeeded
1075                assert_preserved(o, l);
1076            }
1077        }
1078    }
1079
1080    #[test]
1081    fn test_strong_count() {
1082        let buffer = Buffer::from_iter(std::iter::repeat_n(0_u8, 100));
1083        assert_eq!(buffer.strong_count(), 1);
1084
1085        let buffer2 = buffer.clone();
1086        assert_eq!(buffer.strong_count(), 2);
1087
1088        let buffer3 = buffer2.clone();
1089        assert_eq!(buffer.strong_count(), 3);
1090
1091        drop(buffer);
1092        assert_eq!(buffer2.strong_count(), 2);
1093        assert_eq!(buffer3.strong_count(), 2);
1094
1095        // Strong count does not increase on move
1096        let capture = move || {
1097            assert_eq!(buffer3.strong_count(), 2);
1098        };
1099
1100        capture();
1101        assert_eq!(buffer2.strong_count(), 2);
1102
1103        drop(capture);
1104        assert_eq!(buffer2.strong_count(), 1);
1105    }
1106
1107    #[test]
1108    fn into_mutable_should_return_error_for_sliced_owned_buffer_when_ptr_offset_is_not_0() {
1109        let original_buffer_data = [1_u8, 2, 3, 4, 5, 6, 7, 8];
1110        for (slice_from, slice_length) in [
1111            (original_buffer_data.len(), 0),
1112            (2, 4),
1113            (2, original_buffer_data.len() - 2),
1114        ] {
1115            let buffer = Buffer::from(original_buffer_data);
1116            let sliced = buffer.slice_with_length(slice_from, slice_length);
1117            drop(buffer); // Keep only 1 owner
1118            assert_ne!(sliced.ptr_offset(), 0);
1119
1120            sliced
1121                .into_mutable()
1122                .expect_err("should not convert sliced buffer when ptr_offset is not 0");
1123        }
1124    }
1125
1126    #[test]
1127    fn into_mutable_should_allow_converting_sliced_owned_buffer_when_ptr_offset_is_0() {
1128        let original_buffer_data = [1_u8, 2, 3, 4, 5, 6, 7, 8];
1129        for slice_length in [0, original_buffer_data.len() - 2] {
1130            let buffer = Buffer::from(original_buffer_data);
1131            let sliced = buffer.slice_with_length(0, slice_length);
1132            drop(buffer); // Keep only 1 owner
1133            assert_eq!(sliced.ptr_offset(), 0);
1134
1135            let original_ptr = sliced.data_ptr();
1136
1137            let mutable = sliced
1138                        .into_mutable()
1139                        .unwrap_or_else(|_| panic!("should allow converting to mutable when not sliced from end when slice_length is {slice_length}"));
1140
1141            let buffer_back: Buffer = mutable.into();
1142            assert_eq!(buffer_back.data_ptr(), original_ptr);
1143
1144            let expected = Buffer::from(original_buffer_data).slice_with_length(0, slice_length);
1145            assert_eq!(buffer_back.as_slice(), expected.as_slice());
1146        }
1147    }
1148
1149    #[test]
1150    #[cfg(feature = "pool")]
1151    fn test_shrink_to_fit_panicking_reservation() {
1152        use std::panic::{AssertUnwindSafe, catch_unwind};
1153
1154        use crate::pool::{MemoryPool, MemoryReservation};
1155
1156        #[derive(Debug)]
1157        struct PanicPool;
1158
1159        #[derive(Debug)]
1160        struct PanicReservation {
1161            panicked: bool,
1162        }
1163
1164        impl MemoryReservation for PanicReservation {
1165            fn size(&self) -> usize {
1166                0
1167            }
1168            fn resize(&mut self, _: usize) {
1169                if !self.panicked {
1170                    self.panicked = true;
1171                    panic!("intentional panic in resize");
1172                }
1173            }
1174        }
1175
1176        impl MemoryPool for PanicPool {
1177            fn reserve(&self, _: usize) -> Box<dyn MemoryReservation> {
1178                Box::new(PanicReservation { panicked: false })
1179            }
1180            fn available(&self) -> isize {
1181                isize::MAX
1182            }
1183            fn used(&self) -> usize {
1184                0
1185            }
1186            fn capacity(&self) -> usize {
1187                usize::MAX
1188            }
1189        }
1190
1191        let pool = PanicPool;
1192        let data: Vec<u8> = (0..8).collect();
1193        let mut buf = Buffer::from_slice_ref(data.as_slice());
1194        buf.claim(&pool);
1195
1196        // shrink_to_fit panics because PanicReservation::resize panics, but
1197        // Buffer::ptr must stay consistent with Bytes::ptr (no use-after-free).
1198        let _ = catch_unwind(AssertUnwindSafe(|| buf.shrink_to_fit()));
1199
1200        assert_eq!(buf.as_slice(), data.as_slice());
1201    }
1202}