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 // SAFETY: `set_start` checks `cnt <= len` before advancing within this live, exclusively
454 // owned view.
455 unsafe {
456 self.storage.set_start(cnt);
457 }
458 }
459
460 /// Splits the bytes into two at the given index.
461 ///
462 /// Returns `None` if `at > len`.
463 #[inline]
464 #[must_use]
465 pub fn split_to_checked(&mut self, at: usize) -> Option<Bytes> {
466 if at <= self.len() {
467 Some(Bytes {
468 storage: self.storage.split_to(at),
469 })
470 } else {
471 None
472 }
473 }
474
475 /// Shortens the buffer, keeping the first `len` bytes and dropping the
476 /// rest.
477 ///
478 /// If `len` is greater than the buffer's current length, this has no
479 /// effect.
480 ///
481 /// `truncate(0)` on a buffer that is not shared with any other handle
482 /// also reclaims the capacity in front of the current view, see
483 /// [`clear`](Self::clear).
484 ///
485 /// # Examples
486 ///
487 /// ```
488 /// use ntex_bytes::BytesMut;
489 ///
490 /// let mut buf = BytesMut::copy_from_slice(&b"hello world"[..]);
491 /// buf.truncate(5);
492 /// assert_eq!(buf, b"hello"[..]);
493 /// ```
494 #[inline]
495 pub fn truncate(&mut self, len: usize) {
496 self.storage.truncate(len);
497 }
498
499 /// Clears the buffer, removing all data.
500 ///
501 /// If no other handle refers to the underlying buffer (see
502 /// [`is_unique`](Self::is_unique)), the view is reset to the start of the
503 /// allocation, so the full capacity becomes available again.
504 ///
505 /// # Examples
506 ///
507 /// ```
508 /// use ntex_bytes::BytesMut;
509 ///
510 /// let mut buf = BytesMut::copy_from_slice(&b"hello world"[..]);
511 /// buf.clear();
512 /// assert!(buf.is_empty());
513 /// ```
514 #[inline]
515 pub fn clear(&mut self) {
516 self.truncate(0);
517 }
518
519 /// Resizes the buffer so that `len` is equal to `new_len`.
520 ///
521 /// If `new_len` is greater than `len`, the buffer is extended by the
522 /// difference with each additional byte set to `value`. If `new_len` is
523 /// less than `len`, the buffer is simply truncated.
524 ///
525 /// # Panics
526 ///
527 /// Panics if `new_len` exceeds `u32::MAX` minus the buffer
528 /// header size, just under 4 GiB.
529 ///
530 /// # Examples
531 ///
532 /// ```
533 /// use ntex_bytes::BytesMut;
534 ///
535 /// let mut buf = BytesMut::new();
536 ///
537 /// buf.resize(3, 0x1);
538 /// assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
539 ///
540 /// buf.resize(2, 0x2);
541 /// assert_eq!(&buf[..], &[0x1, 0x1]);
542 ///
543 /// buf.resize(4, 0x3);
544 /// assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
545 /// ```
546 #[inline]
547 pub fn resize(&mut self, new_len: usize, value: u8) {
548 self.storage.resize(new_len, value);
549 }
550
551 /// Sets the length of the buffer.
552 ///
553 /// This will explicitly set the size of the buffer without actually
554 /// modifying the data, so it is up to the caller to ensure that the data
555 /// has been initialized.
556 ///
557 /// # Examples
558 ///
559 /// ```
560 /// use ntex_bytes::BytesMut;
561 ///
562 /// let mut b = BytesMut::copy_from_slice(&b"hello world"[..]);
563 ///
564 /// unsafe {
565 /// b.set_len(5);
566 /// }
567 ///
568 /// assert_eq!(&b[..], b"hello");
569 ///
570 /// unsafe {
571 /// b.set_len(11);
572 /// }
573 ///
574 /// assert_eq!(&b[..], b"hello world");
575 /// ```
576 ///
577 /// # Safety
578 ///
579 /// Caller must ensure that data has been initialized.
580 ///
581 /// # Panics
582 ///
583 /// Panics if `len > self.capacity()`.
584 #[inline]
585 pub unsafe fn set_len(&mut self, len: usize) {
586 self.storage.set_len(len);
587 }
588
589 /// Reserves capacity for at least `additional` more bytes to be inserted
590 /// into the given `BytesMut`.
591 ///
592 /// Before allocating new buffer space, the function will attempt to reclaim
593 /// space in the existing buffer. If the current handle references a small
594 /// view in the original buffer and all other handles have been dropped,
595 /// and the requested capacity is less than or equal to the existing
596 /// buffer's capacity, then the current view will be copied to the front of
597 /// the buffer and the handle will take ownership of the full buffer.
598 ///
599 /// Otherwise a unique buffer that is not a pooled page is reallocated,
600 /// often in place, and a new buffer is allocated in all other cases. The
601 /// new capacity is at least twice the current length, so appending in
602 /// small steps reallocates a logarithmic number of times. Use
603 /// [`reserve_exact`](Self::reserve_exact) to avoid the doubling.
604 ///
605 /// A buffer with a [`page_size`](Self::page_size) moves to a page of the
606 /// smallest size that fits the new capacity, but not smaller than its
607 /// current page size, the old page returns to the page cache. Above the
608 /// largest page size, a regular buffer without a page size is allocated.
609 ///
610 /// # Panics
611 ///
612 /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
613 /// header size, just under 4 GiB.
614 ///
615 /// # Examples
616 ///
617 /// In the following example, a new buffer is allocated.
618 ///
619 /// ```
620 /// use ntex_bytes::BytesMut;
621 ///
622 /// let mut buf = BytesMut::copy_from_slice(&b"hello"[..]);
623 /// buf.reserve(64);
624 /// assert!(buf.capacity() >= 69);
625 /// ```
626 ///
627 /// In the following example, the existing buffer is reclaimed.
628 ///
629 /// ```
630 /// use ntex_bytes::{BytesMut, BufMut};
631 ///
632 /// let mut buf = BytesMut::with_capacity(128);
633 /// buf.put(&[0; 64][..]);
634 ///
635 /// let ptr = buf.as_ptr();
636 /// let other = buf.take();
637 ///
638 /// assert!(buf.is_empty());
639 /// assert_eq!(buf.capacity(), 64);
640 ///
641 /// drop(other);
642 /// buf.reserve(128);
643 ///
644 /// assert_eq!(buf.capacity(), 128);
645 /// assert_eq!(buf.as_ptr(), ptr);
646 /// ```
647 #[inline]
648 pub fn reserve(&mut self, additional: usize) {
649 self.storage.reserve(additional);
650 }
651
652 /// Reserves capacity for exactly `additional` more bytes to be inserted
653 /// into the given `BytesMut`.
654 ///
655 /// Behaves like [`reserve`](Self::reserve), it reclaims the existing buffer
656 /// when possible and reallocates a unique buffer, but a new allocation is
657 /// sized to hold exactly `additional` more bytes instead of growing to at
658 /// least twice the current length. The allocation size is the new capacity
659 /// plus the buffer header, [`METADATA_SIZE`](crate::METADATA_SIZE) bytes.
660 /// The contents are not moved when the buffer already has enough remaining
661 /// capacity.
662 ///
663 /// The capacity is not rounded up to a page size, a buffer with a
664 /// [`page_size`](Self::page_size) loses it unless the new capacity is a page
665 /// capacity.
666 ///
667 /// # Panics
668 ///
669 /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
670 /// header size, just under 4 GiB.
671 ///
672 /// # Examples
673 ///
674 /// ```
675 /// use ntex_bytes::BytesMut;
676 ///
677 /// let mut buf = BytesMut::copy_from_slice(&[0; 1000][..]);
678 /// buf.reserve_exact(24);
679 /// assert_eq!(buf.capacity(), 1024);
680 ///
681 /// // enough remaining capacity keeps the current buffer
682 /// let ptr = buf.as_ptr();
683 /// buf.reserve_exact(24);
684 /// assert_eq!(buf.as_ptr(), ptr);
685 /// ```
686 #[inline]
687 pub fn reserve_exact(&mut self, additional: usize) {
688 self.storage.reserve_exact(additional);
689 }
690
691 /// Grows the buffer by one step if its remaining capacity is less than
692 /// the low threshold of its page size.
693 ///
694 /// Nothing happens when the remaining capacity is at least
695 /// [`BytePageSize::low`](crate::BytePageSize::low) of the buffer's
696 /// [`page_size`](Self::page_size), 1 KiB for a 16 KiB page and 4 KiB
697 /// for a buffer without a page size.
698 ///
699 /// If the allocation holds the data and
700 /// [`BytePageSize::half_capacity`](crate::BytePageSize::half_capacity)
701 /// more bytes, it is reused: a unique buffer moves its data to the start
702 /// of the allocation, a shared buffer with a page size moves to a page of
703 /// the same size. Otherwise a buffer with a page size moves to a page of
704 /// the next larger page size, the old page returns to the page cache. A
705 /// buffer without a page size, or with the largest page size, grows its
706 /// capacity by its current capacity, by at least 112 bytes (104 with the
707 /// `tracker` feature) and by at most 64 KiB, like [`reserve_exact`](Self::reserve_exact) does: a unique
708 /// buffer is reallocated, often in place, otherwise the data is copied
709 /// into a new buffer.
710 ///
711 /// # Panics
712 ///
713 /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
714 /// header size, just under 4 GiB.
715 ///
716 /// # Examples
717 ///
718 /// ```
719 /// use ntex_bytes::{BytePageSize, BytesMut};
720 ///
721 /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
722 /// buf.extend_from_slice(b"hello");
723 ///
724 /// // the remaining capacity is above the low threshold, the buffer is kept
725 /// buf.reserve_more();
726 /// assert_eq!(buf.page_size(), BytePageSize::Size4);
727 ///
728 /// buf.extend_from_slice(&[0; 4000]);
729 /// buf.reserve_more();
730 /// assert_eq!(buf.page_size(), BytePageSize::Size8);
731 /// assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
732 /// assert_eq!(&buf[..5], b"hello");
733 ///
734 /// // consumed data makes room, the page is compacted in place
735 /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
736 /// buf.extend_from_slice(&[0; 4000]);
737 /// buf.advance_to(3990);
738 /// buf.reserve_more();
739 /// assert_eq!(buf.page_size(), BytePageSize::Size4);
740 /// assert_eq!(buf.capacity(), BytePageSize::Size4.capacity());
741 ///
742 /// let mut buf = BytesMut::with_capacity(1000);
743 /// buf.reserve_more();
744 /// assert_eq!(buf.capacity(), 2000);
745 ///
746 /// let mut buf = BytesMut::with_capacity(1024 * 1024);
747 /// buf.extend_from_slice(&vec![0; 1024 * 1024]);
748 /// buf.reserve_more();
749 /// assert_eq!(buf.capacity(), 1024 * 1024 + 64 * 1024);
750 /// ```
751 #[inline]
752 pub fn reserve_more(&mut self) {
753 self.storage.reserve_more();
754 }
755
756 /// Appends a byte slice to the buffer.
757 ///
758 /// Additional capacity is reserved automatically when needed.
759 ///
760 /// # Examples
761 ///
762 /// ```
763 /// use ntex_bytes::BytesMut;
764 ///
765 /// let mut buf = BytesMut::with_capacity(0);
766 /// buf.extend_from_slice(b"aaabbb");
767 /// buf.extend_from_slice(b"cccddd");
768 ///
769 /// assert_eq!(b"aaabbbcccddd", &buf[..]);
770 /// ```
771 #[inline]
772 pub fn extend_from_slice(&mut self, extend: &[u8]) {
773 self.put_slice(extend);
774 }
775
776 /// Returns an iterator over the bytes contained by the buffer.
777 ///
778 /// # Examples
779 ///
780 /// ```
781 /// use ntex_bytes::{Buf, BytesMut};
782 ///
783 /// let buf = BytesMut::copy_from_slice(&b"abc"[..]);
784 /// let mut iter = buf.iter();
785 ///
786 /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
787 /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
788 /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
789 /// assert_eq!(iter.next(), None);
790 /// ```
791 #[inline]
792 pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
793 self.chunk().iter()
794 }
795}
796
797impl_buf!(BytesMut {});
798
799impl_slice_traits!(BytesMut);
800
801impl_partial_eq!(BytesMut);
802
803impl BufMut for BytesMut {
804 #[inline]
805 fn remaining_mut(&self) -> usize {
806 self.storage.remaining()
807 }
808
809 #[inline]
810 unsafe fn advance_mut(&mut self, cnt: usize) {
811 // This call will panic if `cnt` is too big
812 self.storage.set_len(self.len() + cnt);
813 }
814
815 #[inline]
816 fn chunk_mut(&mut self) -> &mut UninitSlice {
817 self.storage.spare_mut()
818 }
819
820 #[inline]
821 fn put<T: Buf>(&mut self, mut src: T)
822 where
823 Self: Sized,
824 {
825 self.reserve(src.remaining());
826 while src.has_remaining() {
827 let chunk = src.chunk();
828 let len = chunk.len();
829 self.put_slice(chunk);
830 src.advance(len);
831 }
832 }
833
834 #[inline]
835 fn put_slice(&mut self, src: &[u8]) {
836 self.reserve(src.len());
837 self.storage.put_slice_partial(src);
838 }
839
840 #[inline]
841 fn put_u8(&mut self, n: u8) {
842 self.reserve(1);
843 self.storage.put_u8(n);
844 }
845
846 #[inline]
847 fn put_i8(&mut self, n: i8) {
848 self.put_u8(n as u8);
849 }
850}
851
852/// Interop with the `bytes` crate: like `bytes::BytesMut`, the buffer grows on
853/// demand, so `remaining_mut()` reports `usize::MAX - len` and `chunk_mut()`
854/// is never empty. The native [`BufMut`] impl reports spare capacity instead.
855// SAFETY: Chunks expose only allocated spare bytes, and advancement checks capacity before exposing
856// caller-initialized data.
857unsafe impl bytes::buf::BufMut for BytesMut {
858 #[inline]
859 fn remaining_mut(&self) -> usize {
860 usize::MAX - self.len()
861 }
862
863 #[inline]
864 unsafe fn advance_mut(&mut self, cnt: usize) {
865 let remaining = BufMut::remaining_mut(self);
866 assert!(
867 cnt <= remaining,
868 "cannot advance past `remaining_mut`: {cnt:?} <= {remaining:?}"
869 );
870 BufMut::advance_mut(self, cnt);
871 }
872
873 #[inline]
874 fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
875 if BufMut::remaining_mut(self) == 0 {
876 self.reserve(64);
877 }
878 // SAFETY: The live buffer exclusively owns its spare capacity, which is exactly the
879 // returned range.
880 unsafe {
881 let ptr = self.storage.as_ptr();
882 bytes::buf::UninitSlice::from_raw_parts_mut(
883 ptr.add(self.len()),
884 BufMut::remaining_mut(self),
885 )
886 }
887 }
888
889 #[inline]
890 fn put<T: bytes::buf::Buf>(&mut self, mut src: T)
891 where
892 Self: Sized,
893 {
894 self.reserve(src.remaining());
895 while src.has_remaining() {
896 let chunk = src.chunk();
897 let len = chunk.len();
898 BufMut::put_slice(self, chunk);
899 src.advance(len);
900 }
901 }
902
903 #[inline]
904 fn put_slice(&mut self, src: &[u8]) {
905 BufMut::put_slice(self, src);
906 }
907
908 #[inline]
909 fn put_bytes(&mut self, val: u8, cnt: usize) {
910 self.reserve(cnt);
911 // SAFETY: `reserve(cnt)` provides writable space, and all `cnt` bytes are initialized
912 // before advancing.
913 unsafe {
914 ptr::write_bytes(self.storage.as_ptr().add(self.len()), val, cnt);
915 BufMut::advance_mut(self, cnt);
916 }
917 }
918
919 #[inline]
920 fn put_u8(&mut self, n: u8) {
921 BufMut::put_u8(self, n);
922 }
923
924 #[inline]
925 fn put_i8(&mut self, n: i8) {
926 BufMut::put_i8(self, n);
927 }
928}
929
930impl AsMut<[u8]> for BytesMut {
931 #[inline]
932 fn as_mut(&mut self) -> &mut [u8] {
933 self.storage.as_mut()
934 }
935}
936
937impl DerefMut for BytesMut {
938 #[inline]
939 fn deref_mut(&mut self) -> &mut [u8] {
940 self.storage.as_mut()
941 }
942}
943
944impl Eq for BytesMut {}
945
946impl PartialEq for BytesMut {
947 #[inline]
948 fn eq(&self, other: &BytesMut) -> bool {
949 self.storage.as_ref() == other.storage.as_ref()
950 }
951}
952
953impl borrow::BorrowMut<[u8]> for BytesMut {
954 #[inline]
955 fn borrow_mut(&mut self) -> &mut [u8] {
956 self.as_mut()
957 }
958}
959
960impl PartialEq<Bytes> for BytesMut {
961 fn eq(&self, other: &Bytes) -> bool {
962 other[..] == self[..]
963 }
964}
965
966impl PartialEq<BytesMut> for Bytes {
967 fn eq(&self, other: &BytesMut) -> bool {
968 *other == *self
969 }
970}
971
972impl_read!(BytesMut);
973
974impl io::Write for BytesMut {
975 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
976 self.extend_from_slice(src);
977 Ok(src.len())
978 }
979
980 fn flush(&mut self) -> Result<(), io::Error> {
981 Ok(())
982 }
983}
984
985impl fmt::Write for BytesMut {
986 #[inline]
987 fn write_str(&mut self, s: &str) -> fmt::Result {
988 self.extend_from_slice(s.as_bytes());
989 Ok(())
990 }
991}
992
993impl Clone for BytesMut {
994 #[inline]
995 fn clone(&self) -> BytesMut {
996 BytesMut::from(&self[..])
997 }
998}
999
1000impl FromIterator<u8> for BytesMut {
1001 fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
1002 let iter = into_iter.into_iter();
1003 let (min, maybe_max) = iter.size_hint();
1004
1005 let mut out = BytesMut::with_capacity(maybe_max.unwrap_or(min));
1006 out.extend(iter);
1007 out
1008 }
1009}
1010
1011impl<'a> FromIterator<&'a u8> for BytesMut {
1012 fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
1013 into_iter.into_iter().copied().collect::<BytesMut>()
1014 }
1015}
1016
1017impl Extend<u8> for BytesMut {
1018 fn extend<T>(&mut self, iter: T)
1019 where
1020 T: IntoIterator<Item = u8>,
1021 {
1022 let iter = iter.into_iter();
1023 self.reserve(iter.size_hint().0);
1024 for b in iter {
1025 self.put_u8(b);
1026 }
1027 }
1028}
1029
1030impl<'a> Extend<&'a u8> for BytesMut {
1031 fn extend<T>(&mut self, iter: T)
1032 where
1033 T: IntoIterator<Item = &'a u8>,
1034 {
1035 self.extend(iter.into_iter().copied());
1036 }
1037}
1038
1039impl From<BytesMut> for Bytes {
1040 #[inline]
1041 fn from(b: BytesMut) -> Self {
1042 b.freeze()
1043 }
1044}
1045
1046impl<'a> From<&'a [u8]> for BytesMut {
1047 #[inline]
1048 fn from(src: &'a [u8]) -> BytesMut {
1049 BytesMut::copy_from_slice(src)
1050 }
1051}
1052
1053impl<const N: usize> From<[u8; N]> for BytesMut {
1054 #[inline]
1055 fn from(src: [u8; N]) -> BytesMut {
1056 BytesMut::copy_from_slice(src)
1057 }
1058}
1059
1060impl<'a, const N: usize> From<&'a [u8; N]> for BytesMut {
1061 #[inline]
1062 fn from(src: &'a [u8; N]) -> BytesMut {
1063 BytesMut::copy_from_slice(src)
1064 }
1065}
1066
1067impl<'a> From<&'a str> for BytesMut {
1068 #[inline]
1069 fn from(src: &'a str) -> BytesMut {
1070 BytesMut::from(src.as_bytes())
1071 }
1072}
1073
1074impl From<Bytes> for BytesMut {
1075 #[inline]
1076 fn from(src: Bytes) -> BytesMut {
1077 match src.storage.try_into_vec() {
1078 Ok(storage) => BytesMut { storage },
1079 Err(storage) => BytesMut::copy_from_slice(storage.as_ref()),
1080 }
1081 }
1082}
1083
1084impl From<&Bytes> for BytesMut {
1085 #[inline]
1086 fn from(src: &Bytes) -> BytesMut {
1087 BytesMut::copy_from_slice(&src[..])
1088 }
1089}
1090
1091#[cfg(test)]
1092mod tests {
1093 use super::*;
1094
1095 /// STATEMENT: Repeated small writes grow `BytesMut` amortized rather than reallocating for every write.
1096 ///
1097 /// HOW:
1098 /// - Append eight bytes 10,000 times and check length and at most 16 capacity changes.
1099 /// - Format 1,000 eight-digit numbers into another buffer and verify length and bounded capacity.
1100 #[test]
1101 fn growth_is_amortized() {
1102 let mut buf = BytesMut::with_capacity(0);
1103 let mut cap = buf.capacity();
1104 let mut reallocs = 0;
1105 for _ in 0..10_000 {
1106 buf.put_slice(b"abcdefgh");
1107 if buf.capacity() != cap {
1108 reallocs += 1;
1109 cap = buf.capacity();
1110 }
1111 }
1112 assert_eq!(buf.len(), 80_000);
1113 assert!(reallocs <= 16, "reallocs: {reallocs}");
1114
1115 // writes through `io::Write` and `fmt::Write` grow the same way
1116 let mut buf = BytesMut::with_capacity(0);
1117 for i in 0..1000 {
1118 std::fmt::Write::write_fmt(&mut buf, format_args!("{i:08}")).unwrap();
1119 }
1120 assert_eq!(buf.len(), 8000);
1121 assert!(buf.capacity() < 16_000);
1122 }
1123
1124 /// STATEMENT: Large reservations for small live data allocate only the requested additional capacity.
1125 ///
1126 /// HOW:
1127 /// - Reserve 64 KiB after `hello` and check capacity equals live length plus the request.
1128 /// - Split 1,000 bytes from a shared 1,024-byte buffer, reserve 4,096 for the tail, and check capacity and head data.
1129 #[test]
1130 fn growth_of_little_data_is_exact() {
1131 let mut buf = BytesMut::copy_from_slice(b"hello");
1132 buf.reserve(64 * 1024);
1133 assert_eq!(buf.capacity(), 5 + 64 * 1024);
1134
1135 // a buffer shared with split off `Bytes`
1136 let mut buf = BytesMut::with_capacity(1024);
1137 buf.extend_from_slice(&[1; 1024]);
1138 let head = buf.split_to(1000);
1139 buf.reserve(4096);
1140 assert_eq!(buf.capacity(), 24 + 4096);
1141 assert_eq!(&head[..], &[1; 1000][..]);
1142 }
1143
1144 /// STATEMENT: Converting uniquely owned vector-backed `Bytes` to `BytesMut` reuses spare capacity.
1145 ///
1146 /// HOW:
1147 /// - Freeze 64 bytes in a 256-byte buffer, convert back, and check pointer, contents, and capacity.
1148 /// - Fill the spare capacity and verify the pointer and appended bytes.
1149 #[test]
1150 fn from_unique_bytes_reuses_buffer() {
1151 let mut buf = BytesMut::with_capacity(256);
1152 buf.extend_from_slice(&[1; 64]);
1153 let b = buf.freeze();
1154 let ptr = b.as_ptr();
1155
1156 let mut m = BytesMut::from(b);
1157 assert_eq!(m.as_ptr(), ptr);
1158 assert_eq!(&m[..], &[1; 64][..]);
1159 assert_eq!(m.capacity(), 256);
1160
1161 // spare capacity past the view is writable
1162 m.extend_from_slice(&[2; 192]);
1163 assert_eq!(m.as_ptr(), ptr);
1164 assert_eq!(&m[64..], &[2; 192][..]);
1165 }
1166
1167 /// STATEMENT: A unique `Bytes` subview regains writable capacity after its visible end when made mutable.
1168 ///
1169 /// HOW:
1170 /// - Drop a split 32-byte head, truncate the tail, convert to `BytesMut`, and check pointer and tail capacity.
1171 /// - Append 160 bytes and verify old and new content without relocation.
1172 #[test]
1173 fn from_unique_bytes_subview() {
1174 let mut buf = BytesMut::with_capacity(256);
1175 buf.extend_from_slice(&[1; 128]);
1176 let mut b = buf.freeze();
1177 let head = b.split_to(32);
1178 drop(head);
1179 b.truncate(64);
1180 let ptr = b.as_ptr();
1181
1182 let mut m = BytesMut::from(b);
1183 assert_eq!(m.as_ptr(), ptr);
1184 assert_eq!(m.len(), 64);
1185 assert_eq!(m.capacity(), 256 - 32);
1186
1187 // the dropped tail of the view is spare capacity again
1188 m.extend_from_slice(&[3; 160]);
1189 assert_eq!(m.as_ptr(), ptr);
1190 assert_eq!(&m[..64], &[1; 64][..]);
1191 assert_eq!(&m[64..], &[3; 160][..]);
1192 }
1193
1194 /// STATEMENT: Converting shared `Bytes` to `BytesMut` copies rather than exposing shared mutable storage.
1195 ///
1196 /// HOW:
1197 /// - Keep a clone, convert its sibling, mutate it, and check distinct pointers and unchanged clone data.
1198 /// - Convert bytes taken from a live `BytesMut` and verify later writes to the original do not alter the copy.
1199 #[test]
1200 fn from_shared_bytes_copies() {
1201 let b = BytesMut::copy_from_slice([1; 64]).freeze();
1202 let b2 = b.clone();
1203
1204 let mut m = BytesMut::from(b);
1205 assert_ne!(m.as_ptr(), b2.as_ptr());
1206 m[0] = 2;
1207 assert_eq!(&b2[..], &[1; 64][..]);
1208
1209 // the buffer is still referenced by a `BytesMut`
1210 let mut buf = BytesMut::with_capacity(256);
1211 buf.extend_from_slice(&[1; 64]);
1212 let b = buf.take();
1213 let m = BytesMut::from(b);
1214 assert_ne!(m.as_ptr(), buf.as_ptr());
1215 buf.extend_from_slice(&[2; 64]);
1216 assert_eq!(&m[..], &[1; 64][..]);
1217 }
1218
1219 // Run under miri: without `Acquire`, the header update races with the
1220 // read made by the other thread before it released its handle.
1221 /// STATEMENT: Reclaiming unique `Bytes` storage synchronizes with a different thread releasing its view.
1222 ///
1223 /// HOW:
1224 /// - Read a cloned view on another thread while retrying `try_into_vec` until unique ownership is available.
1225 /// - Check pointer reuse, mutate the reclaimed buffer, and verify the joined thread read the original byte.
1226 #[test]
1227 fn from_bytes_synchronizes_with_release() {
1228 let b = BytesMut::copy_from_slice([1; 64]).freeze();
1229 let other = b.clone();
1230 let handle = std::thread::spawn(move || {
1231 let val = other[0];
1232 drop(other);
1233 val
1234 });
1235
1236 let ptr = b.as_ptr();
1237 let mut storage = b.storage;
1238 let mut m = loop {
1239 match storage.try_into_vec() {
1240 Ok(storage) => break BytesMut { storage },
1241 Err(st) => {
1242 storage = st;
1243 std::thread::yield_now();
1244 }
1245 }
1246 };
1247 assert_eq!(m.as_ptr(), ptr);
1248 m[0] = 2;
1249 assert_eq!(handle.join().unwrap(), 1);
1250 }
1251
1252 /// STATEMENT: Inline and static `Bytes` convert to mutable buffers with unchanged contents.
1253 ///
1254 /// HOW:
1255 /// - Convert inline `inline` bytes and a static 64-byte array with `BytesMut::from` and compare their contents.
1256 #[test]
1257 fn from_inline_and_static_bytes() {
1258 let m = BytesMut::from(Bytes::copy_from_slice(b"inline"));
1259 assert_eq!(&m[..], b"inline");
1260
1261 let m = BytesMut::from(Bytes::from_static(&[1; 64]));
1262 assert_eq!(&m[..], &[1; 64][..]);
1263 }
1264
1265 /// STATEMENT: Reading `BytesMut` consumes its contents without touching unused destination bytes.
1266 ///
1267 /// HOW:
1268 /// - Read `123` into a ten-byte zeroed array and verify a three-byte read, an empty buffer, and seven untouched zeros.
1269 #[test]
1270 fn bvec_read() {
1271 use std::io::Read;
1272
1273 let mut b = BytesMut::copy_from_slice(b"123");
1274
1275 let mut buf = [0; 10];
1276 assert_eq!(b.read(&mut buf).unwrap(), 3);
1277 assert_eq!(b.len(), 0);
1278 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1279 }
1280
1281 /// STATEMENT: Converting borrowed `Bytes` yields independently extensible mutable contents.
1282 ///
1283 /// HOW:
1284 /// - Convert borrowed static `hello`, append `!`, and verify `hello!` while the source remains `hello`.
1285 #[test]
1286 fn from_bytes_ref() {
1287 let b = Bytes::from_static(b"hello");
1288 let mut m = BytesMut::from(&b);
1289 m.extend_from_slice(b"!");
1290 assert_eq!(m, "hello!");
1291 assert_eq!(b, "hello");
1292 }
1293}