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}