Skip to main content

ntex_bytes/
bvec.rs

1use std::{borrow, fmt, io, ops::DerefMut, ptr};
2
3use crate::{Buf, BufMut, BytePageSize, Bytes, buf::UninitSlice, stvec::StorageVec};
4
5/// A unique reference to a contiguous slice of memory.
6///
7/// `BytesMut` represents a unique view into a potentially shared memory region.
8/// Given the uniqueness guarantee, owners of `BytesMut` handles are able to
9/// mutate the memory. It is similar to a `Vec<u8>` but with fewer copies and
10/// allocations. It also always allocates.
11///
12/// For more detail, see [`Bytes`].
13///
14/// # Growth
15///
16/// Safe write operations such as [`BufMut::put_slice`], [`BufMut::put_u8`], and
17/// [`extend_from_slice`](Self::extend_from_slice) reserve additional capacity
18/// when needed. Use [`reserve`](Self::reserve) when the required capacity is
19/// known in advance to avoid repeated allocation.
20///
21/// # Examples
22///
23/// ```
24/// use ntex_bytes::{BytesMut, BufMut};
25///
26/// let mut buf = BytesMut::with_capacity(64);
27///
28/// buf.put_u8(b'h');
29/// buf.put_u8(b'e');
30/// buf.put_slice(b"llo");
31///
32/// assert_eq!(&buf[..], b"hello");
33///
34/// // Freeze the buffer so that it can be shared
35/// let a = buf.freeze();
36///
37/// // This does not allocate, instead `b` points to the same memory.
38/// let b = a.clone();
39///
40/// assert_eq!(a, b"hello");
41/// assert_eq!(b, b"hello");
42/// ```
43pub struct BytesMut {
44    pub(crate) storage: StorageVec,
45}
46
47impl BytesMut {
48    /// Creates a new `BytesMut` with the specified capacity.
49    ///
50    /// The returned `BytesMut` will be able to hold `capacity` bytes
51    /// without reallocating.
52    ///
53    /// It is important to note that this function does not specify the length
54    /// of the returned `BytesMut`, but only the capacity.
55    ///
56    /// # Panics
57    ///
58    /// Panics if `capacity` exceeds `u32::MAX` minus the buffer
59    /// header size, just under 4 GiB.
60    ///
61    /// # Examples
62    ///
63    /// ```
64    /// use ntex_bytes::{BytesMut, BufMut};
65    ///
66    /// let mut bytes = BytesMut::with_capacity(64);
67    ///
68    /// // `bytes` contains no data, even though there is capacity
69    /// assert_eq!(bytes.len(), 0);
70    ///
71    /// bytes.put(&b"hello world"[..]);
72    ///
73    /// assert_eq!(&bytes[..], b"hello world");
74    /// ```
75    #[inline]
76    #[must_use]
77    pub fn with_capacity(capacity: usize) -> BytesMut {
78        BytesMut {
79            storage: StorageVec::with_capacity(capacity),
80        }
81    }
82
83    /// Creates a new empty `BytesMut` backed by a page of the specified size.
84    ///
85    /// The buffer has the [`capacity`](BytePageSize::capacity) of the page
86    /// size. Pages are taken from the current thread's page cache, and the
87    /// page returns to the cache of the thread that drops the last reference
88    /// to it, including [`Bytes`] split off the buffer. If the cache has no
89    /// page of the requested size but has one of the next smaller size, see
90    /// [`BytePageSize::prev`], that page is used instead, the buffer then has
91    /// the smaller capacity and page size.
92    ///
93    /// When the buffer grows, it moves to a page of the size that fits the
94    /// new capacity, see [`reserve`](Self::reserve). Growth always uses a
95    /// page of exactly that size. Above the largest page size the buffer is
96    /// a regular allocation without a page size, it is freed when dropped.
97    ///
98    /// [`BytePageSize::Unset`] has the allocation size of
99    /// [`BytePageSize::Size64`], it creates a `Size64` page.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use ntex_bytes::{BytePageSize, BytesMut};
105    ///
106    /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
107    /// assert_eq!(buf.capacity(), BytePageSize::Size4.capacity());
108    /// assert_eq!(buf.page_size(), BytePageSize::Size4);
109    ///
110    /// buf.extend_from_slice(&[0; 5000]);
111    /// assert_eq!(buf.page_size(), BytePageSize::Size8);
112    /// ```
113    #[inline]
114    #[must_use]
115    pub fn with_page_size(size: BytePageSize) -> BytesMut {
116        let size = if size == BytePageSize::Unset {
117            BytePageSize::Size64
118        } else {
119            size
120        };
121        BytesMut {
122            storage: StorageVec::sized(size),
123        }
124    }
125
126    /// Creates a new `BytesMut` from the page cache, like
127    /// [`with_page_size`](Self::with_page_size), with the allocation charged
128    /// to `tracker`.
129    ///
130    /// The allocation stays charged while any `BytesMut` or [`Bytes`]
131    /// handle refers to it. A buffer that grows into a new allocation
132    /// charges it to the same tracker, the old allocation is uncharged when
133    /// its last handle is dropped. Copies made by [`Clone`], conversions or
134    /// [`Bytes::trimdown`] are not charged.
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use ntex_bytes::{BytePageSize, BytesMut, BytesTracker};
140    ///
141    /// let tracker = BytesTracker::new();
142    /// let buf = BytesMut::with_page_size_in(BytePageSize::Size4, &tracker);
143    /// assert_eq!(tracker.snapshot().live_bytes, 4096);
144    /// assert_eq!(tracker.snapshot().live_allocations, 1);
145    ///
146    /// drop(buf);
147    /// assert_eq!(tracker.snapshot().live_bytes, 0);
148    /// ```
149    #[cfg(feature = "tracker")]
150    #[cfg_attr(docsrs, doc(cfg(feature = "tracker")))]
151    #[inline]
152    #[must_use]
153    pub fn with_page_size_in(size: BytePageSize, tracker: &crate::BytesTracker) -> BytesMut {
154        let size = if size == BytePageSize::Unset {
155            BytePageSize::Size64
156        } else {
157            size
158        };
159        BytesMut {
160            storage: StorageVec::sized_in(size, tracker),
161        }
162    }
163
164    /// Charges the allocation of the buffer to `tracker`.
165    ///
166    /// The allocation stays charged as described in
167    /// [`with_page_size_in`](Self::with_page_size_in). If the allocation is
168    /// charged to a different tracker, the charge moves to `tracker`, also
169    /// while it is shared with [`Bytes`] handles. Setting the tracker the
170    /// buffer is already charged to does nothing.
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// use ntex_bytes::{BytesMut, BytesTracker};
176    ///
177    /// let tracker = BytesTracker::new();
178    /// let mut buf = BytesMut::with_capacity(256);
179    /// buf.extend_from_slice(&[0; 128]);
180    ///
181    /// let head = buf.split_to(64);
182    /// buf.set_tracker(&tracker);
183    /// assert!(buf.tracker().unwrap().ptr_eq(&tracker));
184    /// assert_eq!(tracker.snapshot().live_allocations, 1);
185    ///
186    /// let other = BytesTracker::new();
187    /// buf.set_tracker(&other);
188    /// assert_eq!(tracker.snapshot().live_allocations, 0);
189    /// assert_eq!(other.snapshot().live_allocations, 1);
190    ///
191    /// drop((buf, head));
192    /// assert_eq!(other.snapshot().live_allocations, 0);
193    /// ```
194    #[cfg(feature = "tracker")]
195    #[cfg_attr(docsrs, doc(cfg(feature = "tracker")))]
196    #[inline]
197    pub fn set_tracker(&mut self, tracker: &crate::BytesTracker) {
198        self.storage.set_tracker(tracker);
199    }
200
201    /// Returns the tracker charged with the allocation of the buffer.
202    #[cfg(feature = "tracker")]
203    #[cfg_attr(docsrs, doc(cfg(feature = "tracker")))]
204    #[inline]
205    #[must_use]
206    pub fn tracker(&self) -> Option<&crate::BytesTracker> {
207        self.storage.tracker()
208    }
209
210    /// Returns the page size of the buffer.
211    ///
212    /// The page size is derived from the allocation size, a buffer whose
213    /// allocation, header included, is exactly a page size belongs to that
214    /// page size. This covers buffers created by
215    /// [`with_page_size`](Self::with_page_size), converted from a pooled
216    /// [`BytePage`](crate::BytePage), or created with a page
217    /// [`capacity`](BytePageSize::capacity). They return to the page cache
218    /// when the last reference is dropped. Other buffers return
219    /// [`BytePageSize::Unset`], they are freed when dropped.
220    #[inline]
221    pub fn page_size(&self) -> BytePageSize {
222        self.storage.page_size()
223    }
224
225    /// Creates a `BytesMut` by copying a byte slice.
226    #[inline]
227    #[must_use]
228    pub fn copy_from_slice<T: AsRef<[u8]>>(src: T) -> Self {
229        let slice = src.as_ref();
230        BytesMut {
231            storage: StorageVec::from_slice(slice.len(), slice),
232        }
233    }
234
235    /// Creates a new `BytesMut` with default capacity.
236    ///
237    /// Resulting object has length 0 and unspecified capacity.
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// use ntex_bytes::{BytesMut, BufMut};
243    ///
244    /// let mut bytes = BytesMut::new();
245    ///
246    /// assert_eq!(0, bytes.len());
247    ///
248    /// bytes.reserve(2);
249    /// bytes.put_slice(b"xy");
250    ///
251    /// assert_eq!(&b"xy"[..], &bytes[..]);
252    /// ```
253    #[inline]
254    #[must_use]
255    pub fn new() -> BytesMut {
256        BytesMut {
257            storage: StorageVec::with_capacity(crate::storage::MIN_CAPACITY),
258        }
259    }
260
261    /// Returns the number of bytes contained in this `BytesMut`.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// use ntex_bytes::BytesMut;
267    ///
268    /// let b = BytesMut::copy_from_slice(&b"hello"[..]);
269    /// assert_eq!(b.len(), 5);
270    /// ```
271    #[inline]
272    pub fn len(&self) -> usize {
273        self.storage.len()
274    }
275
276    /// Returns `true` if the buffer is empty.
277    ///
278    /// # Examples
279    ///
280    /// ```
281    /// use ntex_bytes::BytesMut;
282    ///
283    /// let b = BytesMut::with_capacity(64);
284    /// assert!(b.is_empty());
285    /// ```
286    #[inline]
287    pub fn is_empty(&self) -> bool {
288        self.storage.len() == 0
289    }
290
291    /// Returns the number of bytes the `BytesMut` can hold without reallocating.
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// use ntex_bytes::BytesMut;
297    ///
298    /// let b = BytesMut::with_capacity(64);
299    /// assert_eq!(b.capacity(), 64);
300    /// ```
301    #[inline]
302    pub fn capacity(&self) -> usize {
303        self.storage.capacity()
304    }
305
306    /// Returns `true` if no other handle refers to the underlying buffer.
307    ///
308    /// Values split off with [`split_to`](Self::split_to) or frozen into
309    /// [`Bytes`] share the buffer with `self`. While they exist, clearing
310    /// `self` does not reclaim the capacity in front of it, and the whole
311    /// allocation stays alive as long as any of them does.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// use ntex_bytes::BytesMut;
317    ///
318    /// let mut buf = BytesMut::with_capacity(64);
319    /// buf.extend_from_slice(&[0; 32]);
320    /// assert!(buf.is_unique());
321    ///
322    /// let head = buf.split_to(30);
323    /// assert!(!buf.is_unique());
324    ///
325    /// drop(head);
326    /// assert!(buf.is_unique());
327    /// ```
328    #[inline]
329    pub fn is_unique(&self) -> bool {
330        self.storage.is_unique()
331    }
332
333    /// Converts `self` into an immutable `Bytes`.
334    ///
335    /// The conversion is zero cost and is used to indicate that the slice
336    /// referenced by the handle will no longer be mutated. Once the conversion
337    /// is done, the handle can be cloned and shared across threads.
338    ///
339    /// # Examples
340    ///
341    /// ```
342    /// use ntex_bytes::{BytesMut, BufMut};
343    /// use std::thread;
344    ///
345    /// let mut b = BytesMut::with_capacity(64);
346    /// b.put_slice(b"hello world");
347    /// let b1 = b.freeze();
348    /// let b2 = b1.clone();
349    ///
350    /// let th = thread::spawn(move || {
351    ///     assert_eq!(b1, b"hello world");
352    /// });
353    ///
354    /// assert_eq!(b2, b"hello world");
355    /// th.join().unwrap();
356    /// ```
357    #[inline]
358    #[must_use]
359    pub fn freeze(self) -> Bytes {
360        Bytes {
361            storage: self.storage.freeze(),
362        }
363    }
364
365    /// Removes the bytes from the current view, returning them in a
366    /// `Bytes` instance.
367    ///
368    /// Afterwards, `self` will be empty, but will retain any additional
369    /// capacity that it had before the operation. This is identical to
370    /// `self.split_to(self.len())`.
371    ///
372    /// This is an `O(1)` operation that just increases the reference count and
373    /// sets a few indices.
374    ///
375    /// # Examples
376    ///
377    /// ```
378    /// use ntex_bytes::{BytesMut, BufMut};
379    ///
380    /// let mut buf = BytesMut::with_capacity(1024);
381    /// buf.put(&b"hello world"[..]);
382    ///
383    /// let other = buf.take();
384    ///
385    /// assert!(buf.is_empty());
386    /// assert_eq!(1013, buf.capacity());
387    ///
388    /// assert_eq!(other, b"hello world"[..]);
389    /// ```
390    #[inline]
391    #[must_use]
392    pub fn take(&mut self) -> Bytes {
393        Bytes {
394            storage: self.storage.split_to(self.len()),
395        }
396    }
397
398    /// Splits the buffer into two at the given index.
399    ///
400    /// Afterwards `self` contains elements `[at, len)`, and the returned `Bytes`
401    /// contains elements `[0, at)`.
402    ///
403    /// This is an `O(1)` operation that just increases the reference count and
404    /// sets a few indices.
405    ///
406    /// # Examples
407    ///
408    /// ```
409    /// use ntex_bytes::BytesMut;
410    ///
411    /// let mut a = BytesMut::copy_from_slice(&b"hello world"[..]);
412    /// let mut b = a.split_to(5);
413    ///
414    /// a[0] = b'!';
415    ///
416    /// assert_eq!(&a[..], b"!world");
417    /// assert_eq!(&b[..], b"hello");
418    /// ```
419    ///
420    /// # Panics
421    ///
422    /// Panics if `at > len`.
423    #[inline]
424    #[must_use]
425    pub fn split_to(&mut self, at: usize) -> Bytes {
426        self.split_to_checked(at)
427            .expect("at value must be <= self.len()`")
428    }
429
430    /// Advance the internal cursor.
431    ///
432    /// Afterwards `self` contains elements `[cnt, len)`.
433    /// This is an `O(1)` operation.
434    ///
435    /// # Examples
436    ///
437    /// ```
438    /// use ntex_bytes::BytesMut;
439    ///
440    /// let mut a = BytesMut::copy_from_slice(&b"hello world"[..]);
441    /// a.advance_to(5);
442    ///
443    /// a[0] = b'!';
444    ///
445    /// assert_eq!(&a[..], b"!world");
446    /// ```
447    ///
448    /// # Panics
449    ///
450    /// Panics if `cnt > len`.
451    #[inline]
452    pub fn advance_to(&mut self, cnt: usize) {
453        unsafe {
454            self.storage.set_start(cnt);
455        }
456    }
457
458    /// Splits the bytes into two at the given index.
459    ///
460    /// Returns `None` if `at > len`.
461    #[inline]
462    #[must_use]
463    pub fn split_to_checked(&mut self, at: usize) -> Option<Bytes> {
464        if at <= self.len() {
465            Some(Bytes {
466                storage: self.storage.split_to(at),
467            })
468        } else {
469            None
470        }
471    }
472
473    /// Shortens the buffer, keeping the first `len` bytes and dropping the
474    /// rest.
475    ///
476    /// If `len` is greater than the buffer's current length, this has no
477    /// effect.
478    ///
479    /// `truncate(0)` on a buffer that is not shared with any other handle
480    /// also reclaims the capacity in front of the current view, see
481    /// [`clear`](Self::clear).
482    ///
483    /// # Examples
484    ///
485    /// ```
486    /// use ntex_bytes::BytesMut;
487    ///
488    /// let mut buf = BytesMut::copy_from_slice(&b"hello world"[..]);
489    /// buf.truncate(5);
490    /// assert_eq!(buf, b"hello"[..]);
491    /// ```
492    #[inline]
493    pub fn truncate(&mut self, len: usize) {
494        self.storage.truncate(len);
495    }
496
497    /// Clears the buffer, removing all data.
498    ///
499    /// If no other handle refers to the underlying buffer (see
500    /// [`is_unique`](Self::is_unique)), the view is reset to the start of the
501    /// allocation, so the full capacity becomes available again.
502    ///
503    /// # Examples
504    ///
505    /// ```
506    /// use ntex_bytes::BytesMut;
507    ///
508    /// let mut buf = BytesMut::copy_from_slice(&b"hello world"[..]);
509    /// buf.clear();
510    /// assert!(buf.is_empty());
511    /// ```
512    #[inline]
513    pub fn clear(&mut self) {
514        self.truncate(0);
515    }
516
517    /// Resizes the buffer so that `len` is equal to `new_len`.
518    ///
519    /// If `new_len` is greater than `len`, the buffer is extended by the
520    /// difference with each additional byte set to `value`. If `new_len` is
521    /// less than `len`, the buffer is simply truncated.
522    ///
523    /// # Panics
524    ///
525    /// Panics if `new_len` exceeds `u32::MAX` minus the buffer
526    /// header size, just under 4 GiB.
527    ///
528    /// # Examples
529    ///
530    /// ```
531    /// use ntex_bytes::BytesMut;
532    ///
533    /// let mut buf = BytesMut::new();
534    ///
535    /// buf.resize(3, 0x1);
536    /// assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
537    ///
538    /// buf.resize(2, 0x2);
539    /// assert_eq!(&buf[..], &[0x1, 0x1]);
540    ///
541    /// buf.resize(4, 0x3);
542    /// assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
543    /// ```
544    #[inline]
545    pub fn resize(&mut self, new_len: usize, value: u8) {
546        self.storage.resize(new_len, value);
547    }
548
549    /// Sets the length of the buffer.
550    ///
551    /// This will explicitly set the size of the buffer without actually
552    /// modifying the data, so it is up to the caller to ensure that the data
553    /// has been initialized.
554    ///
555    /// # Examples
556    ///
557    /// ```
558    /// use ntex_bytes::BytesMut;
559    ///
560    /// let mut b = BytesMut::copy_from_slice(&b"hello world"[..]);
561    ///
562    /// unsafe {
563    ///     b.set_len(5);
564    /// }
565    ///
566    /// assert_eq!(&b[..], b"hello");
567    ///
568    /// unsafe {
569    ///     b.set_len(11);
570    /// }
571    ///
572    /// assert_eq!(&b[..], b"hello world");
573    /// ```
574    ///
575    /// # Safety
576    ///
577    /// Caller must ensure that data has been initialized.
578    ///
579    /// # Panics
580    ///
581    /// Panics if `len > self.capacity()`.
582    #[inline]
583    pub unsafe fn set_len(&mut self, len: usize) {
584        self.storage.set_len(len);
585    }
586
587    /// Reserves capacity for at least `additional` more bytes to be inserted
588    /// into the given `BytesMut`.
589    ///
590    /// Before allocating new buffer space, the function will attempt to reclaim
591    /// space in the existing buffer. If the current handle references a small
592    /// view in the original buffer and all other handles have been dropped,
593    /// and the requested capacity is less than or equal to the existing
594    /// buffer's capacity, then the current view will be copied to the front of
595    /// the buffer and the handle will take ownership of the full buffer.
596    ///
597    /// Otherwise a unique buffer that is not a pooled page is reallocated,
598    /// often in place, and a new buffer is allocated in all other cases. The
599    /// new capacity is at least twice the current length, so appending in
600    /// small steps reallocates a logarithmic number of times. Use
601    /// [`reserve_exact`](Self::reserve_exact) to avoid the doubling.
602    ///
603    /// A buffer with a [`page_size`](Self::page_size) moves to a page of the
604    /// smallest size that fits the new capacity, but not smaller than its
605    /// current page size, the old page returns to the page cache. Above the
606    /// largest page size, a regular buffer without a page size is allocated.
607    ///
608    /// # Panics
609    ///
610    /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
611    /// header size, just under 4 GiB.
612    ///
613    /// # Examples
614    ///
615    /// In the following example, a new buffer is allocated.
616    ///
617    /// ```
618    /// use ntex_bytes::BytesMut;
619    ///
620    /// let mut buf = BytesMut::copy_from_slice(&b"hello"[..]);
621    /// buf.reserve(64);
622    /// assert!(buf.capacity() >= 69);
623    /// ```
624    ///
625    /// In the following example, the existing buffer is reclaimed.
626    ///
627    /// ```
628    /// use ntex_bytes::{BytesMut, BufMut};
629    ///
630    /// let mut buf = BytesMut::with_capacity(128);
631    /// buf.put(&[0; 64][..]);
632    ///
633    /// let ptr = buf.as_ptr();
634    /// let other = buf.take();
635    ///
636    /// assert!(buf.is_empty());
637    /// assert_eq!(buf.capacity(), 64);
638    ///
639    /// drop(other);
640    /// buf.reserve(128);
641    ///
642    /// assert_eq!(buf.capacity(), 128);
643    /// assert_eq!(buf.as_ptr(), ptr);
644    /// ```
645    #[inline]
646    pub fn reserve(&mut self, additional: usize) {
647        self.storage.reserve(additional);
648    }
649
650    /// Reserves capacity for exactly `additional` more bytes to be inserted
651    /// into the given `BytesMut`.
652    ///
653    /// Behaves like [`reserve`](Self::reserve), it reclaims the existing buffer
654    /// when possible and reallocates a unique buffer, but a new allocation is
655    /// sized to hold exactly `additional` more bytes instead of growing to at
656    /// least twice the current length. The allocation size is the new capacity
657    /// plus the buffer header, [`METADATA_SIZE`](crate::METADATA_SIZE) bytes.
658    /// The contents are not moved when the buffer already has enough remaining
659    /// capacity.
660    ///
661    /// The capacity is not rounded up to a page size, a buffer with a
662    /// [`page_size`](Self::page_size) loses it unless the new capacity is a page
663    /// capacity.
664    ///
665    /// # Panics
666    ///
667    /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
668    /// header size, just under 4 GiB.
669    ///
670    /// # Examples
671    ///
672    /// ```
673    /// use ntex_bytes::BytesMut;
674    ///
675    /// let mut buf = BytesMut::copy_from_slice(&[0; 1000][..]);
676    /// buf.reserve_exact(24);
677    /// assert_eq!(buf.capacity(), 1024);
678    ///
679    /// // enough remaining capacity keeps the current buffer
680    /// let ptr = buf.as_ptr();
681    /// buf.reserve_exact(24);
682    /// assert_eq!(buf.as_ptr(), ptr);
683    /// ```
684    #[inline]
685    pub fn reserve_exact(&mut self, additional: usize) {
686        self.storage.reserve_exact(additional);
687    }
688
689    /// Grows the buffer by one step if its remaining capacity is less than
690    /// the low threshold of its page size.
691    ///
692    /// Nothing happens when the remaining capacity is at least
693    /// [`BytePageSize::low`](crate::BytePageSize::low) of the buffer's
694    /// [`page_size`](Self::page_size), 1 KiB for a 16 KiB page and 4 KiB
695    /// for a buffer without a page size.
696    ///
697    /// If the allocation holds the data and
698    /// [`BytePageSize::half_capacity`](crate::BytePageSize::half_capacity)
699    /// more bytes, it is reused: a unique buffer moves its data to the start
700    /// of the allocation, a shared buffer with a page size moves to a page of
701    /// the same size. Otherwise a buffer with a page size moves to a page of
702    /// the next larger page size, the old page returns to the page cache. A
703    /// buffer without a page size, or with the largest page size, grows its
704    /// capacity by its current capacity, by at least 112 bytes (104 with the
705    /// `tracker` feature) and by at most 64 KiB, like [`reserve_exact`](Self::reserve_exact) does: a unique
706    /// buffer is reallocated, often in place, otherwise the data is copied
707    /// into a new buffer.
708    ///
709    /// # Panics
710    ///
711    /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
712    /// header size, just under 4 GiB.
713    ///
714    /// # Examples
715    ///
716    /// ```
717    /// use ntex_bytes::{BytePageSize, BytesMut};
718    ///
719    /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
720    /// buf.extend_from_slice(b"hello");
721    ///
722    /// // the remaining capacity is above the low threshold, the buffer is kept
723    /// buf.reserve_more();
724    /// assert_eq!(buf.page_size(), BytePageSize::Size4);
725    ///
726    /// buf.extend_from_slice(&[0; 4000]);
727    /// buf.reserve_more();
728    /// assert_eq!(buf.page_size(), BytePageSize::Size8);
729    /// assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
730    /// assert_eq!(&buf[..5], b"hello");
731    ///
732    /// // consumed data makes room, the page is compacted in place
733    /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
734    /// buf.extend_from_slice(&[0; 4000]);
735    /// buf.advance_to(3990);
736    /// buf.reserve_more();
737    /// assert_eq!(buf.page_size(), BytePageSize::Size4);
738    /// assert_eq!(buf.capacity(), BytePageSize::Size4.capacity());
739    ///
740    /// let mut buf = BytesMut::with_capacity(1000);
741    /// buf.reserve_more();
742    /// assert_eq!(buf.capacity(), 2000);
743    ///
744    /// let mut buf = BytesMut::with_capacity(1024 * 1024);
745    /// buf.extend_from_slice(&vec![0; 1024 * 1024]);
746    /// buf.reserve_more();
747    /// assert_eq!(buf.capacity(), 1024 * 1024 + 64 * 1024);
748    /// ```
749    #[inline]
750    pub fn reserve_more(&mut self) {
751        self.storage.reserve_more();
752    }
753
754    /// Appends a byte slice to the buffer.
755    ///
756    /// Additional capacity is reserved automatically when needed.
757    ///
758    /// # Examples
759    ///
760    /// ```
761    /// use ntex_bytes::BytesMut;
762    ///
763    /// let mut buf = BytesMut::with_capacity(0);
764    /// buf.extend_from_slice(b"aaabbb");
765    /// buf.extend_from_slice(b"cccddd");
766    ///
767    /// assert_eq!(b"aaabbbcccddd", &buf[..]);
768    /// ```
769    #[inline]
770    pub fn extend_from_slice(&mut self, extend: &[u8]) {
771        self.put_slice(extend);
772    }
773
774    /// Returns an iterator over the bytes contained by the buffer.
775    ///
776    /// # Examples
777    ///
778    /// ```
779    /// use ntex_bytes::{Buf, BytesMut};
780    ///
781    /// let buf = BytesMut::copy_from_slice(&b"abc"[..]);
782    /// let mut iter = buf.iter();
783    ///
784    /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
785    /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
786    /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
787    /// assert_eq!(iter.next(), None);
788    /// ```
789    #[inline]
790    pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
791        self.chunk().iter()
792    }
793}
794
795impl_buf!(BytesMut {});
796
797impl_slice_traits!(BytesMut);
798
799impl_partial_eq!(BytesMut);
800
801impl BufMut for BytesMut {
802    #[inline]
803    fn remaining_mut(&self) -> usize {
804        self.storage.remaining()
805    }
806
807    #[inline]
808    unsafe fn advance_mut(&mut self, cnt: usize) {
809        // This call will panic if `cnt` is too big
810        self.storage.set_len(self.len() + cnt);
811    }
812
813    #[inline]
814    fn chunk_mut(&mut self) -> &mut UninitSlice {
815        self.storage.spare_mut()
816    }
817
818    #[inline]
819    fn put<T: Buf>(&mut self, mut src: T)
820    where
821        Self: Sized,
822    {
823        self.reserve(src.remaining());
824        while src.has_remaining() {
825            let chunk = src.chunk();
826            let len = chunk.len();
827            self.put_slice(chunk);
828            src.advance(len);
829        }
830    }
831
832    #[inline]
833    fn put_slice(&mut self, src: &[u8]) {
834        self.reserve(src.len());
835        self.storage.put_slice_partial(src);
836    }
837
838    #[inline]
839    fn put_u8(&mut self, n: u8) {
840        self.reserve(1);
841        self.storage.put_u8(n);
842    }
843
844    #[inline]
845    fn put_i8(&mut self, n: i8) {
846        self.put_u8(n as u8);
847    }
848}
849
850/// Interop with the `bytes` crate: like `bytes::BytesMut`, the buffer grows on
851/// demand, so `remaining_mut()` reports `usize::MAX - len` and `chunk_mut()`
852/// is never empty. The native [`BufMut`] impl reports spare capacity instead.
853unsafe impl bytes::buf::BufMut for BytesMut {
854    #[inline]
855    fn remaining_mut(&self) -> usize {
856        usize::MAX - self.len()
857    }
858
859    #[inline]
860    unsafe fn advance_mut(&mut self, cnt: usize) {
861        let remaining = BufMut::remaining_mut(self);
862        assert!(
863            cnt <= remaining,
864            "cannot advance past `remaining_mut`: {cnt:?} <= {remaining:?}"
865        );
866        BufMut::advance_mut(self, cnt);
867    }
868
869    #[inline]
870    fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
871        if BufMut::remaining_mut(self) == 0 {
872            self.reserve(64);
873        }
874        unsafe {
875            let ptr = self.storage.as_ptr();
876            bytes::buf::UninitSlice::from_raw_parts_mut(
877                ptr.add(self.len()),
878                BufMut::remaining_mut(self),
879            )
880        }
881    }
882
883    #[inline]
884    fn put<T: bytes::buf::Buf>(&mut self, mut src: T)
885    where
886        Self: Sized,
887    {
888        self.reserve(src.remaining());
889        while src.has_remaining() {
890            let chunk = src.chunk();
891            let len = chunk.len();
892            BufMut::put_slice(self, chunk);
893            src.advance(len);
894        }
895    }
896
897    #[inline]
898    fn put_slice(&mut self, src: &[u8]) {
899        BufMut::put_slice(self, src);
900    }
901
902    #[inline]
903    fn put_bytes(&mut self, val: u8, cnt: usize) {
904        self.reserve(cnt);
905        unsafe {
906            ptr::write_bytes(self.storage.as_ptr().add(self.len()), val, cnt);
907            BufMut::advance_mut(self, cnt);
908        }
909    }
910
911    #[inline]
912    fn put_u8(&mut self, n: u8) {
913        BufMut::put_u8(self, n);
914    }
915
916    #[inline]
917    fn put_i8(&mut self, n: i8) {
918        BufMut::put_i8(self, n);
919    }
920}
921
922impl AsMut<[u8]> for BytesMut {
923    #[inline]
924    fn as_mut(&mut self) -> &mut [u8] {
925        self.storage.as_mut()
926    }
927}
928
929impl DerefMut for BytesMut {
930    #[inline]
931    fn deref_mut(&mut self) -> &mut [u8] {
932        self.storage.as_mut()
933    }
934}
935
936impl Eq for BytesMut {}
937
938impl PartialEq for BytesMut {
939    #[inline]
940    fn eq(&self, other: &BytesMut) -> bool {
941        self.storage.as_ref() == other.storage.as_ref()
942    }
943}
944
945impl borrow::BorrowMut<[u8]> for BytesMut {
946    #[inline]
947    fn borrow_mut(&mut self) -> &mut [u8] {
948        self.as_mut()
949    }
950}
951
952impl PartialEq<Bytes> for BytesMut {
953    fn eq(&self, other: &Bytes) -> bool {
954        other[..] == self[..]
955    }
956}
957
958impl PartialEq<BytesMut> for Bytes {
959    fn eq(&self, other: &BytesMut) -> bool {
960        *other == *self
961    }
962}
963
964impl_read!(BytesMut);
965
966impl io::Write for BytesMut {
967    fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
968        self.extend_from_slice(src);
969        Ok(src.len())
970    }
971
972    fn flush(&mut self) -> Result<(), io::Error> {
973        Ok(())
974    }
975}
976
977impl fmt::Write for BytesMut {
978    #[inline]
979    fn write_str(&mut self, s: &str) -> fmt::Result {
980        self.extend_from_slice(s.as_bytes());
981        Ok(())
982    }
983}
984
985impl Clone for BytesMut {
986    #[inline]
987    fn clone(&self) -> BytesMut {
988        BytesMut::from(&self[..])
989    }
990}
991
992impl FromIterator<u8> for BytesMut {
993    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
994        let iter = into_iter.into_iter();
995        let (min, maybe_max) = iter.size_hint();
996
997        let mut out = BytesMut::with_capacity(maybe_max.unwrap_or(min));
998        out.extend(iter);
999        out
1000    }
1001}
1002
1003impl<'a> FromIterator<&'a u8> for BytesMut {
1004    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
1005        into_iter.into_iter().copied().collect::<BytesMut>()
1006    }
1007}
1008
1009impl Extend<u8> for BytesMut {
1010    fn extend<T>(&mut self, iter: T)
1011    where
1012        T: IntoIterator<Item = u8>,
1013    {
1014        let iter = iter.into_iter();
1015        self.reserve(iter.size_hint().0);
1016        for b in iter {
1017            self.put_u8(b);
1018        }
1019    }
1020}
1021
1022impl<'a> Extend<&'a u8> for BytesMut {
1023    fn extend<T>(&mut self, iter: T)
1024    where
1025        T: IntoIterator<Item = &'a u8>,
1026    {
1027        self.extend(iter.into_iter().copied());
1028    }
1029}
1030
1031impl From<BytesMut> for Bytes {
1032    #[inline]
1033    fn from(b: BytesMut) -> Self {
1034        b.freeze()
1035    }
1036}
1037
1038impl<'a> From<&'a [u8]> for BytesMut {
1039    #[inline]
1040    fn from(src: &'a [u8]) -> BytesMut {
1041        BytesMut::copy_from_slice(src)
1042    }
1043}
1044
1045impl<const N: usize> From<[u8; N]> for BytesMut {
1046    #[inline]
1047    fn from(src: [u8; N]) -> BytesMut {
1048        BytesMut::copy_from_slice(src)
1049    }
1050}
1051
1052impl<'a, const N: usize> From<&'a [u8; N]> for BytesMut {
1053    #[inline]
1054    fn from(src: &'a [u8; N]) -> BytesMut {
1055        BytesMut::copy_from_slice(src)
1056    }
1057}
1058
1059impl<'a> From<&'a str> for BytesMut {
1060    #[inline]
1061    fn from(src: &'a str) -> BytesMut {
1062        BytesMut::from(src.as_bytes())
1063    }
1064}
1065
1066impl From<Bytes> for BytesMut {
1067    #[inline]
1068    fn from(src: Bytes) -> BytesMut {
1069        match src.storage.try_into_vec() {
1070            Ok(storage) => BytesMut { storage },
1071            Err(storage) => BytesMut::copy_from_slice(storage.as_ref()),
1072        }
1073    }
1074}
1075
1076impl From<&Bytes> for BytesMut {
1077    #[inline]
1078    fn from(src: &Bytes) -> BytesMut {
1079        BytesMut::copy_from_slice(&src[..])
1080    }
1081}
1082
1083#[cfg(test)]
1084mod tests {
1085    use super::*;
1086
1087    /// STATEMENT: Repeated small writes grow `BytesMut` amortized rather than reallocating for every write.
1088    ///
1089    /// HOW:
1090    /// - Append eight bytes 10,000 times and check length and at most 16 capacity changes.
1091    /// - Format 1,000 eight-digit numbers into another buffer and verify length and bounded capacity.
1092    #[test]
1093    fn growth_is_amortized() {
1094        let mut buf = BytesMut::with_capacity(0);
1095        let mut cap = buf.capacity();
1096        let mut reallocs = 0;
1097        for _ in 0..10_000 {
1098            buf.put_slice(b"abcdefgh");
1099            if buf.capacity() != cap {
1100                reallocs += 1;
1101                cap = buf.capacity();
1102            }
1103        }
1104        assert_eq!(buf.len(), 80_000);
1105        assert!(reallocs <= 16, "reallocs: {reallocs}");
1106
1107        // writes through `io::Write` and `fmt::Write` grow the same way
1108        let mut buf = BytesMut::with_capacity(0);
1109        for i in 0..1000 {
1110            std::fmt::Write::write_fmt(&mut buf, format_args!("{i:08}")).unwrap();
1111        }
1112        assert_eq!(buf.len(), 8000);
1113        assert!(buf.capacity() < 16_000);
1114    }
1115
1116    /// STATEMENT: Large reservations for small live data allocate only the requested additional capacity.
1117    ///
1118    /// HOW:
1119    /// - Reserve 64 KiB after `hello` and check capacity equals live length plus the request.
1120    /// - Split 1,000 bytes from a shared 1,024-byte buffer, reserve 4,096 for the tail, and check capacity and head data.
1121    #[test]
1122    fn growth_of_little_data_is_exact() {
1123        let mut buf = BytesMut::copy_from_slice(b"hello");
1124        buf.reserve(64 * 1024);
1125        assert_eq!(buf.capacity(), 5 + 64 * 1024);
1126
1127        // a buffer shared with split off `Bytes`
1128        let mut buf = BytesMut::with_capacity(1024);
1129        buf.extend_from_slice(&[1; 1024]);
1130        let head = buf.split_to(1000);
1131        buf.reserve(4096);
1132        assert_eq!(buf.capacity(), 24 + 4096);
1133        assert_eq!(&head[..], &[1; 1000][..]);
1134    }
1135
1136    /// STATEMENT: Converting uniquely owned vector-backed `Bytes` to `BytesMut` reuses spare capacity.
1137    ///
1138    /// HOW:
1139    /// - Freeze 64 bytes in a 256-byte buffer, convert back, and check pointer, contents, and capacity.
1140    /// - Fill the spare capacity and verify the pointer and appended bytes.
1141    #[test]
1142    fn from_unique_bytes_reuses_buffer() {
1143        let mut buf = BytesMut::with_capacity(256);
1144        buf.extend_from_slice(&[1; 64]);
1145        let b = buf.freeze();
1146        let ptr = b.as_ptr();
1147
1148        let mut m = BytesMut::from(b);
1149        assert_eq!(m.as_ptr(), ptr);
1150        assert_eq!(&m[..], &[1; 64][..]);
1151        assert_eq!(m.capacity(), 256);
1152
1153        // spare capacity past the view is writable
1154        m.extend_from_slice(&[2; 192]);
1155        assert_eq!(m.as_ptr(), ptr);
1156        assert_eq!(&m[64..], &[2; 192][..]);
1157    }
1158
1159    /// STATEMENT: A unique `Bytes` subview regains writable capacity after its visible end when made mutable.
1160    ///
1161    /// HOW:
1162    /// - Drop a split 32-byte head, truncate the tail, convert to `BytesMut`, and check pointer and tail capacity.
1163    /// - Append 160 bytes and verify old and new content without relocation.
1164    #[test]
1165    fn from_unique_bytes_subview() {
1166        let mut buf = BytesMut::with_capacity(256);
1167        buf.extend_from_slice(&[1; 128]);
1168        let mut b = buf.freeze();
1169        let head = b.split_to(32);
1170        drop(head);
1171        b.truncate(64);
1172        let ptr = b.as_ptr();
1173
1174        let mut m = BytesMut::from(b);
1175        assert_eq!(m.as_ptr(), ptr);
1176        assert_eq!(m.len(), 64);
1177        assert_eq!(m.capacity(), 256 - 32);
1178
1179        // the dropped tail of the view is spare capacity again
1180        m.extend_from_slice(&[3; 160]);
1181        assert_eq!(m.as_ptr(), ptr);
1182        assert_eq!(&m[..64], &[1; 64][..]);
1183        assert_eq!(&m[64..], &[3; 160][..]);
1184    }
1185
1186    /// STATEMENT: Converting shared `Bytes` to `BytesMut` copies rather than exposing shared mutable storage.
1187    ///
1188    /// HOW:
1189    /// - Keep a clone, convert its sibling, mutate it, and check distinct pointers and unchanged clone data.
1190    /// - Convert bytes taken from a live `BytesMut` and verify later writes to the original do not alter the copy.
1191    #[test]
1192    fn from_shared_bytes_copies() {
1193        let b = BytesMut::copy_from_slice([1; 64]).freeze();
1194        let b2 = b.clone();
1195
1196        let mut m = BytesMut::from(b);
1197        assert_ne!(m.as_ptr(), b2.as_ptr());
1198        m[0] = 2;
1199        assert_eq!(&b2[..], &[1; 64][..]);
1200
1201        // the buffer is still referenced by a `BytesMut`
1202        let mut buf = BytesMut::with_capacity(256);
1203        buf.extend_from_slice(&[1; 64]);
1204        let b = buf.take();
1205        let m = BytesMut::from(b);
1206        assert_ne!(m.as_ptr(), buf.as_ptr());
1207        buf.extend_from_slice(&[2; 64]);
1208        assert_eq!(&m[..], &[1; 64][..]);
1209    }
1210
1211    // Run under miri: without `Acquire`, the header update races with the
1212    // read made by the other thread before it released its handle.
1213    /// STATEMENT: Reclaiming unique `Bytes` storage synchronizes with a different thread releasing its view.
1214    ///
1215    /// HOW:
1216    /// - Read a cloned view on another thread while retrying `try_into_vec` until unique ownership is available.
1217    /// - Check pointer reuse, mutate the reclaimed buffer, and verify the joined thread read the original byte.
1218    #[test]
1219    fn from_bytes_synchronizes_with_release() {
1220        let b = BytesMut::copy_from_slice([1; 64]).freeze();
1221        let other = b.clone();
1222        let handle = std::thread::spawn(move || {
1223            let val = other[0];
1224            drop(other);
1225            val
1226        });
1227
1228        let ptr = b.as_ptr();
1229        let mut storage = b.storage;
1230        let mut m = loop {
1231            match storage.try_into_vec() {
1232                Ok(storage) => break BytesMut { storage },
1233                Err(st) => {
1234                    storage = st;
1235                    std::thread::yield_now();
1236                }
1237            }
1238        };
1239        assert_eq!(m.as_ptr(), ptr);
1240        m[0] = 2;
1241        assert_eq!(handle.join().unwrap(), 1);
1242    }
1243
1244    /// STATEMENT: Inline and static `Bytes` convert to mutable buffers with unchanged contents.
1245    ///
1246    /// HOW:
1247    /// - Convert inline `inline` bytes and a static 64-byte array with `BytesMut::from` and compare their contents.
1248    #[test]
1249    fn from_inline_and_static_bytes() {
1250        let m = BytesMut::from(Bytes::copy_from_slice(b"inline"));
1251        assert_eq!(&m[..], b"inline");
1252
1253        let m = BytesMut::from(Bytes::from_static(&[1; 64]));
1254        assert_eq!(&m[..], &[1; 64][..]);
1255    }
1256
1257    /// STATEMENT: Reading `BytesMut` consumes its contents without touching unused destination bytes.
1258    ///
1259    /// HOW:
1260    /// - Read `123` into a ten-byte zeroed array and verify a three-byte read, an empty buffer, and seven untouched zeros.
1261    #[test]
1262    fn bvec_read() {
1263        use std::io::Read;
1264
1265        let mut b = BytesMut::copy_from_slice(b"123");
1266
1267        let mut buf = [0; 10];
1268        assert_eq!(b.read(&mut buf).unwrap(), 3);
1269        assert_eq!(b.len(), 0);
1270        assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1271    }
1272
1273    /// STATEMENT: Converting borrowed `Bytes` yields independently extensible mutable contents.
1274    ///
1275    /// HOW:
1276    /// - Convert borrowed static `hello`, append `!`, and verify `hello!` while the source remains `hello`.
1277    #[test]
1278    fn from_bytes_ref() {
1279        let b = Bytes::from_static(b"hello");
1280        let mut m = BytesMut::from(&b);
1281        m.extend_from_slice(b"!");
1282        assert_eq!(m, "hello!");
1283        assert_eq!(b, "hello");
1284    }
1285}