Skip to main content

ntex_bytes/
pages.rs

1#![allow(clippy::missing_panics_doc, clippy::box_collection)]
2use std::{borrow::Borrow, cell::Cell, cmp, collections::VecDeque, fmt, io, mem, ops, ptr};
3
4use crate::{BufMut, BytePageSize, ByteString, Bytes, BytesMut};
5use crate::{buf::UninitSlice, storage::StorageVec};
6
7pub struct BytePages {
8    st: Option<Box<Inner>>,
9    current: Option<StorageVec>,
10}
11
12#[derive(Debug)]
13struct Inner {
14    size: BytePageSize,
15    pages: VecDeque<BytePage>,
16}
17
18thread_local! {
19    static CACHE: Cell<Option<Box<Vec<Box<Inner>>>>> = Cell::new(Some(Box::default()));
20}
21const CACHE_SIZE: usize = 128;
22
23impl BytePages {
24    /// Creates a new `BytePages` with the specified page size.
25    ///
26    /// The returned `BytePages` will be hold one page with
27    /// specified capacity.
28    pub fn new(size: BytePageSize) -> Self {
29        debug_assert!(size != BytePageSize::Unset, "Page cannot be Unset");
30
31        let st = CACHE.with(move |c| {
32            let mut cache = c.take().unwrap();
33
34            let item = if let Some(mut item) = cache.pop() {
35                item.size = size;
36                item
37            } else {
38                Box::new(Inner {
39                    size,
40                    pages: VecDeque::with_capacity(8),
41                })
42            };
43            c.set(Some(cache));
44            item
45        });
46
47        BytePages {
48            st: Some(st),
49            current: None,
50        }
51    }
52
53    fn pages(&self) -> &VecDeque<BytePage> {
54        &self.st.as_ref().unwrap().pages
55    }
56
57    fn pages_mut(&mut self) -> &mut VecDeque<BytePage> {
58        &mut self.st.as_mut().unwrap().pages
59    }
60
61    fn push_back(&mut self, page: BytePage) {
62        let pages = &mut self.st.as_mut().unwrap().pages;
63        pages.push_back(page);
64
65        #[cfg(feature = "overuse")]
66        if pages.len() > 32 {
67            let bt = backtrace::Backtrace::new();
68            log::warn!("Number of pages {}\n{bt:?}", pages.len());
69            println!("{bt:?}");
70        }
71    }
72
73    /// Get size of the page.
74    pub fn page_size(&self) -> BytePageSize {
75        self.st.as_ref().unwrap().size
76    }
77
78    /// Sets the page size for new pages.
79    pub fn set_page_size(&mut self, size: BytePageSize) {
80        self.st.as_mut().unwrap().size = size;
81    }
82
83    /// Insert a page to the front of the collection.
84    pub fn prepend<T>(&mut self, buf: T) -> bool
85    where
86        BytePage: From<T>,
87    {
88        let p = BytePage::from(buf);
89        if p.is_empty() {
90            false
91        } else {
92            self.pages_mut().push_front(p);
93            true
94        }
95    }
96
97    /// Appends a new page to the back of the collection.
98    pub fn append<T>(&mut self, buf: T)
99    where
100        BytePage: From<T>,
101    {
102        let p = BytePage::from(buf);
103        if !p.is_empty() {
104            if self.current_len() == 0 {
105                match p.into_storage() {
106                    Ok(st) => {
107                        self.current = Some(st);
108                    }
109                    Err(page) => {
110                        // add buffer to stack
111                        self.push_back(page);
112                    }
113                }
114            } else if p.len() <= self.remaining_mut() {
115                self.put_slice(p.as_ref());
116            } else {
117                let page = self.current.take();
118                let pages = self.pages_mut();
119
120                // push current storage to stack
121                if let Some(page) = page {
122                    pages.push_back(From::from(page));
123                }
124                // add buffer to stack
125                pages.push_back(p);
126
127                #[cfg(feature = "overuse")]
128                if pages.len() > 32 {
129                    let bt = backtrace::Backtrace::new();
130                    log::warn!("Number of pages {}\n{bt:?}", pages.len());
131                    println!("{bt:?}");
132                }
133            }
134        }
135    }
136
137    #[inline]
138    /// Appends the given bytes to this page object.
139    ///
140    /// Tries to write the data into the current page first. If there
141    /// is insufficient space, one or more new pages are allocated as
142    /// needed, and the remaining data is copied into them.
143    pub fn extend_from_slice(&mut self, extend: &[u8]) {
144        self.put_slice(extend);
145    }
146
147    #[inline]
148    /// Gets the total number of pages.
149    pub fn len(&self) -> usize {
150        self.pages()
151            .iter()
152            .fold(self.current_len(), |c, page| c + page.len())
153    }
154
155    fn current_len(&self) -> usize {
156        self.current
157            .as_ref()
158            .map(StorageVec::len)
159            .unwrap_or_default()
160    }
161
162    #[inline]
163    /// Checks if the `BytePages` instance is empty.
164    pub fn is_empty(&self) -> bool {
165        for p in self.pages() {
166            if !p.is_empty() {
167                return false;
168            }
169        }
170        self.current_len() == 0
171    }
172
173    #[inline]
174    /// Returns the total number of pages contained in this object.
175    pub fn num_pages(&self) -> usize {
176        if self.current.is_none() {
177            self.pages().len()
178        } else {
179            self.pages().len() + 1
180        }
181    }
182
183    /// Returns the first page from the collection.
184    pub fn take(&mut self) -> Option<BytePage> {
185        if let Some(page) = self.pages_mut().pop_front() {
186            Some(page)
187        } else {
188            self.current.take().map(BytePage::from)
189        }
190    }
191
192    #[inline]
193    /// Copies all pages into another `BytePages` instance.
194    ///
195    /// Depending on the underlying storage, this operation might be `O(1)` or could
196    /// involve a memory copy.
197    pub fn copy_to(&self, pages: &mut BytePages) {
198        for p in self.pages() {
199            pages.append(p.clone());
200        }
201
202        if let Some(st) = &self.current {
203            pages.append(BytePage::from(Bytes::copy_from_slice(st.as_ref())));
204        }
205    }
206
207    #[inline]
208    /// Moves all pages to another `BytePages` instance.
209    pub fn move_to(&mut self, pages: &mut BytePages) {
210        while let Some(page) = self.take() {
211            pages.append(page);
212        }
213    }
214
215    /// Splits the buffer into two at the given index.
216    ///
217    /// Afterwards, `self` contains elements `[at, len)`, and the returned `BytePage`
218    /// contains elements `[0, at)`.
219    ///
220    /// Depending on the underlying storage, this operation might be `O(1)` or could
221    /// involve a memory copy.
222    #[must_use]
223    pub fn split_to(&mut self, at: usize) -> BytePages {
224        let mut pages = BytePages::new(self.page_size());
225        self.split_into(at, &mut pages);
226        pages
227    }
228
229    /// Splits the buffer, adding the resulting items to the supplied pages object.
230    ///
231    /// Afterwards, `self` contains elements `[at, len)`, and the supplied `BytePage`
232    /// contains elements `[0, at)`.
233    ///
234    /// Depending on the underlying storage, this operation might be `O(1)` or could
235    /// involve a memory copy.
236    pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
237        {
238            let pages = self.pages_mut();
239
240            while let Some(mut page) = pages.pop_front() {
241                let len = cmp::min(page.len(), at);
242                to.append(page.split_to(len));
243
244                if !page.is_empty() {
245                    pages.push_front(page);
246                    return;
247                }
248                at -= len;
249            }
250        }
251        if at > 0
252            && let Some(mut page) = self.take()
253        {
254            let len = cmp::min(page.len(), at);
255            to.append(page.split_to(len));
256            self.append(page);
257        }
258    }
259
260    /// Clears the buffer, removing all data.
261    #[inline]
262    pub fn clear(&mut self) {
263        while self.take().is_some() {}
264    }
265
266    /// Converts `self` into an immutable `Bytes`.
267    #[inline]
268    #[must_use]
269    pub fn freeze(&mut self) -> Bytes {
270        let pages = self.num_pages();
271        if pages == 0 || self.is_empty() {
272            Bytes::new()
273        } else if pages == 1 {
274            self.take().unwrap().freeze()
275        } else {
276            let mut buf = BytesMut::with_capacity(self.len());
277            while let Some(p) = self.take() {
278                buf.extend_from_slice(&p);
279            }
280            buf.freeze()
281        }
282    }
283
284    #[inline]
285    pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
286        if self.pages().is_empty()
287            && self.current.is_none()
288            && let Some(st) = pages.current.take()
289        {
290            self.current = Some(st);
291        }
292    }
293
294    /// Access current page as `BytesMut` object
295    pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
296    where
297        F: FnOnce(&mut BytesMut) -> R,
298    {
299        let mut st = self
300            .current
301            .take()
302            .unwrap_or_else(|| StorageVec::sized(self.page_size()));
303
304        let cap = st.capacity();
305        let mut buf = BytesMut {
306            storage: StorageVec(st.0),
307        };
308
309        let res = f(&mut buf);
310
311        // `buf.storage` cal re-allocate, makes self.current invalid
312        st.0 = buf.storage.0;
313        if buf.capacity() != cap {
314            buf.storage.unsize();
315        }
316        // buf.storage.0 uses same pointer as self.current.0
317        mem::forget(buf);
318
319        // add new page
320        if st.len() >= self.page_size().capacity() {
321            self.push_back(BytePage::from(st));
322        } else {
323            self.current = Some(st);
324        }
325
326        res
327    }
328
329    fn with_current<F, R>(&mut self, f: F) -> R
330    where
331        F: FnOnce(&mut StorageVec) -> R,
332    {
333        let mut st = self
334            .current
335            .take()
336            .unwrap_or_else(|| StorageVec::sized(self.page_size()));
337        let result = f(&mut st);
338
339        // add new page
340        if st.is_full() {
341            self.push_back(BytePage::from(st));
342        } else {
343            self.current = Some(st);
344        }
345
346        result
347    }
348}
349
350impl Drop for BytePages {
351    fn drop(&mut self) {
352        CACHE.with(move |c| {
353            let mut cache = c.take().unwrap();
354            if cache.len() < CACHE_SIZE {
355                let mut st = self.st.take().unwrap();
356                st.pages.clear();
357                cache.push(st);
358            }
359            c.set(Some(cache));
360        });
361    }
362}
363
364impl fmt::Debug for BytePages {
365    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
366        let mut f = fmt.debug_tuple("BytePages");
367        for p in self.pages() {
368            f.field(p);
369        }
370        if let Some(st) = &self.current {
371            f.field(&crate::debug::BsDebug(st.as_ref()));
372        }
373        f.finish()
374    }
375}
376
377impl Default for BytePages {
378    fn default() -> Self {
379        BytePages::new(BytePageSize::Size16)
380    }
381}
382
383impl BufMut for BytePages {
384    #[inline]
385    fn remaining_mut(&self) -> usize {
386        self.current
387            .as_ref()
388            .map(StorageVec::remaining)
389            .unwrap_or_default()
390    }
391
392    #[inline]
393    unsafe fn advance_mut(&mut self, cnt: usize) {
394        // This call will panic if `cnt` is too big
395        let st = self.current.as_mut().unwrap();
396        st.set_len(st.len() + cnt);
397    }
398
399    #[inline]
400    fn chunk_mut(&mut self) -> &mut UninitSlice {
401        unsafe {
402            if self.current.is_none() {
403                self.current = Some(StorageVec::sized(self.page_size()));
404            }
405            // This will never panic as `len` can never become invalid
406            let st = self.current.as_ref().unwrap();
407            let ptr = &mut st.as_ptr();
408            UninitSlice::from_raw_parts_mut(ptr.add(st.len()), self.remaining_mut())
409        }
410    }
411
412    fn put_slice(&mut self, mut src: &[u8]) {
413        while !src.is_empty() {
414            let amount = self.with_current(|st| {
415                let amount = cmp::min(src.len(), st.remaining());
416                unsafe {
417                    let ptr = &mut st.as_ptr();
418                    let chunk =
419                        UninitSlice::from_raw_parts_mut(ptr.add(st.len()), st.remaining());
420
421                    ptr::copy_nonoverlapping(src.as_ptr(), chunk.as_mut_ptr(), amount);
422                    st.set_len(st.len() + amount);
423                }
424                amount
425            });
426
427            src = &src[amount..];
428        }
429    }
430
431    #[inline]
432    fn put_u8(&mut self, n: u8) {
433        self.with_current(|st| st.put_u8(n));
434    }
435
436    #[inline]
437    fn put_i8(&mut self, n: i8) {
438        self.put_u8(n as u8);
439    }
440}
441
442impl Clone for BytePages {
443    fn clone(&self) -> Self {
444        let size = self.page_size();
445        let mut pages = BytePages::new(size);
446        self.copy_to(&mut pages);
447        pages
448    }
449}
450
451impl io::Write for BytePages {
452    fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
453        self.put_slice(src);
454        Ok(src.len())
455    }
456
457    fn flush(&mut self) -> Result<(), io::Error> {
458        Ok(())
459    }
460}
461
462impl From<BytePages> for Bytes {
463    fn from(pages: BytePages) -> Bytes {
464        BytesMut::from(pages).freeze()
465    }
466}
467
468impl From<BytePages> for BytesMut {
469    fn from(mut pages: BytePages) -> BytesMut {
470        let mut buf = BytesMut::with_capacity(pages.len());
471        while let Some(p) = pages.take() {
472            buf.extend_from_slice(&p);
473        }
474        buf
475    }
476}
477
478pub struct BytePage {
479    inner: StorageType,
480}
481
482enum StorageType {
483    Bytes(Bytes),
484    Storage(StorageVec),
485    Vec(Vec<u8>),
486}
487
488impl BytePage {
489    #[inline]
490    /// Returns the number of bytes contained in this `BytePage`.
491    pub fn len(&self) -> usize {
492        match &self.inner {
493            StorageType::Bytes(b) => b.len(),
494            StorageType::Storage(b) => b.len(),
495            StorageType::Vec(b) => b.len(),
496        }
497    }
498
499    #[inline]
500    /// Returns true if the `BytePage` has a length of 0.
501    pub fn is_empty(&self) -> bool {
502        match &self.inner {
503            StorageType::Bytes(b) => b.is_empty(),
504            StorageType::Storage(b) => b.len() == 0,
505            StorageType::Vec(b) => b.is_empty(),
506        }
507    }
508
509    /// Return a raw pointer to data.
510    pub fn as_ptr(&self) -> *const u8 {
511        unsafe {
512            match &self.inner {
513                StorageType::Bytes(b) => b.storage.as_ptr(),
514                StorageType::Storage(b) => b.as_ptr(),
515                StorageType::Vec(b) => b.as_ptr(),
516            }
517        }
518    }
519
520    /// Splits the buffer into two at the given index.
521    ///
522    /// Afterwards, `self` contains elements `[at, len)`, and the returned `BytePage`
523    /// contains elements `[0, at)`.
524    ///
525    /// Depending on the underlying storage, this operation might be `O(1)` or could
526    /// involve a memory copy.
527    #[must_use]
528    pub fn split_to(&mut self, at: usize) -> BytePage {
529        match &mut self.inner {
530            StorageType::Bytes(b) => {
531                let buf = b.split_to(cmp::min(at, b.len()));
532                BytePage {
533                    inner: StorageType::Bytes(buf),
534                }
535            }
536            StorageType::Storage(_) => {
537                let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
538                if let StorageType::Storage(st) = inner {
539                    self.inner = StorageType::Bytes(Bytes {
540                        storage: st.freeze(),
541                    });
542                    self.split_to(at)
543                } else {
544                    unreachable!()
545                }
546            }
547            StorageType::Vec(_) => {
548                let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
549                if let StorageType::Vec(b) = inner {
550                    self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
551                    self.split_to(at)
552                } else {
553                    unreachable!()
554                }
555            }
556        }
557    }
558
559    /// Advance the internal cursor.
560    ///
561    /// Afterwards `self` contains elements `[cnt, len)`.
562    /// This is an `O(1)` operation.
563    ///
564    /// # Panics
565    ///
566    /// Panics if `cnt > len`.
567    #[inline]
568    pub fn advance_to(&mut self, cnt: usize) {
569        match &mut self.inner {
570            StorageType::Bytes(b) => b.advance_to(cnt),
571            StorageType::Storage(b) => unsafe { b.set_start(cnt as u32) },
572            StorageType::Vec(b) => {
573                self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
574            }
575        }
576    }
577
578    /// Converts `self` into an immutable `Bytes`.
579    #[inline]
580    #[must_use]
581    pub fn freeze(self) -> Bytes {
582        match self.inner {
583            StorageType::Bytes(b) => b,
584            StorageType::Storage(st) => Bytes {
585                storage: st.freeze(),
586            },
587            StorageType::Vec(v) => Bytes::from(v),
588        }
589    }
590
591    fn into_storage(self) -> Result<StorageVec, Self> {
592        if let StorageType::Storage(mut st) = self.inner {
593            // SAFETY: Converting back to `StorageVec` requires uniqueness.
594            if !st.is_full() && st.is_unique() {
595                Ok(st)
596            } else {
597                Err(Self {
598                    inner: StorageType::Storage(st),
599                })
600            }
601        } else {
602            Err(self)
603        }
604    }
605}
606
607impl Clone for BytePage {
608    fn clone(&self) -> Self {
609        let inner = match &self.inner {
610            StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
611            StorageType::Storage(st) => {
612                // SAFETY: We garantee that `st` is not being used
613                // for modification. `st` is marked as non-unique after clone
614                StorageType::Storage(unsafe { st.clone() })
615            }
616            StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
617        };
618
619        Self { inner }
620    }
621}
622
623impl AsRef<[u8]> for BytePage {
624    #[inline]
625    fn as_ref(&self) -> &[u8] {
626        match &self.inner {
627            StorageType::Bytes(b) => b.as_ref(),
628            StorageType::Storage(b) => b.as_ref(),
629            StorageType::Vec(b) => b.as_ref(),
630        }
631    }
632}
633
634impl Borrow<[u8]> for BytePage {
635    #[inline]
636    fn borrow(&self) -> &[u8] {
637        self.as_ref()
638    }
639}
640
641impl From<Bytes> for BytePage {
642    fn from(buf: Bytes) -> Self {
643        BytePage {
644            inner: StorageType::Bytes(buf),
645        }
646    }
647}
648
649impl<'a> From<&'a Bytes> for BytePage {
650    fn from(buf: &'a Bytes) -> Self {
651        BytePage {
652            inner: StorageType::Bytes(buf.clone()),
653        }
654    }
655}
656
657impl From<BytesMut> for BytePage {
658    fn from(buf: BytesMut) -> Self {
659        BytePage {
660            inner: StorageType::Storage(buf.storage),
661        }
662    }
663}
664
665impl From<ByteString> for BytePage {
666    fn from(s: ByteString) -> Self {
667        s.into_bytes().into()
668    }
669}
670
671impl<'a> From<&'a ByteString> for BytePage {
672    fn from(s: &'a ByteString) -> Self {
673        s.clone().into_bytes().into()
674    }
675}
676
677impl From<StorageVec> for BytePage {
678    fn from(buf: StorageVec) -> Self {
679        BytePage {
680            inner: StorageType::Storage(buf),
681        }
682    }
683}
684
685impl From<Vec<u8>> for BytePage {
686    fn from(buf: Vec<u8>) -> Self {
687        BytePage {
688            inner: StorageType::Vec(buf),
689        }
690    }
691}
692
693impl From<&'static str> for BytePage {
694    fn from(buf: &'static str) -> Self {
695        BytePage::from(Bytes::from_static(buf.as_bytes()))
696    }
697}
698
699impl From<&'static [u8]> for BytePage {
700    fn from(buf: &'static [u8]) -> Self {
701        BytePage::from(Bytes::from_static(buf))
702    }
703}
704
705impl<const N: usize> From<&'static [u8; N]> for BytePage {
706    fn from(src: &'static [u8; N]) -> Self {
707        BytePage::from(Bytes::from_static(src))
708    }
709}
710
711impl From<BytePage> for Bytes {
712    fn from(page: BytePage) -> Self {
713        match page.inner {
714            StorageType::Bytes(b) => b,
715            StorageType::Storage(storage) => BytesMut { storage }.freeze(),
716            StorageType::Vec(v) => Bytes::copy_from_slice(&v),
717        }
718    }
719}
720
721impl From<BytePage> for BytesMut {
722    fn from(page: BytePage) -> Self {
723        match page.inner {
724            StorageType::Bytes(b) => b.into(),
725            StorageType::Storage(storage) => BytesMut { storage },
726            StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
727        }
728    }
729}
730
731impl PartialEq for BytePage {
732    fn eq(&self, other: &BytePage) -> bool {
733        self.as_ref() == other.as_ref()
734    }
735}
736
737impl<'a> PartialEq<&'a [u8]> for BytePage {
738    fn eq(&self, other: &&'a [u8]) -> bool {
739        self.as_ref() == *other
740    }
741}
742
743impl<'a, const N: usize> PartialEq<&'a [u8; N]> for BytePage {
744    fn eq(&self, other: &&'a [u8; N]) -> bool {
745        self.as_ref() == other.as_ref()
746    }
747}
748
749impl io::Read for BytePage {
750    fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
751        let len = cmp::min(self.len(), dst.len());
752        if len > 0 {
753            dst[..len].copy_from_slice(&self[..len]);
754            self.advance_to(len);
755        }
756        Ok(len)
757    }
758}
759
760impl ops::Deref for BytePage {
761    type Target = [u8];
762
763    #[inline]
764    fn deref(&self) -> &[u8] {
765        self.as_ref()
766    }
767}
768
769impl fmt::Debug for BytePage {
770    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
771        fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
772    }
773}
774
775#[cfg(test)]
776mod tests {
777    use rand::Rng;
778
779    use super::*;
780
781    #[test]
782    fn pages() {
783        // pages
784        let mut pages = BytePages::new(BytePageSize::Size8);
785        assert!(pages.is_empty());
786        assert_eq!(pages.len(), 0);
787        assert_eq!(pages.num_pages(), 0);
788        pages.extend_from_slice(b"b");
789        assert_eq!(pages.len(), 1);
790        assert_eq!(pages.num_pages(), 1);
791        pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
792        assert_eq!(pages.len(), 9217);
793        assert_eq!(pages.num_pages(), 2);
794        assert!(!pages.is_empty());
795
796        let mut pgs = BytePages::new(BytePageSize::Size8);
797        pgs.put_i8(b'a' as i8);
798        let p = pgs.take().unwrap();
799        assert_eq!(p.len(), 1);
800        assert_eq!(p.as_ref(), b"a");
801
802        pgs.extend_from_slice("a".repeat(8 * 1024 - 1).as_bytes());
803        assert_eq!(pgs.num_pages(), 1);
804        pgs.put_u8(b'a');
805        assert_eq!(pgs.num_pages(), 1);
806        assert!(pgs.current.is_none());
807
808        pgs.put_u8(b'a');
809        assert_eq!(pgs.num_pages(), 2);
810
811        pgs.append(Bytes::copy_from_slice("a".repeat(8 * 1024).as_bytes()));
812        assert_eq!(pgs.num_pages(), 3);
813        assert!(pgs.current.is_none());
814
815        // page
816        let p = pages.take().unwrap();
817        assert_eq!(p.len(), 8192);
818        let p = pages.take().unwrap();
819        assert_eq!(p.len(), 1025);
820        assert!(!p.is_empty());
821        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
822        assert_eq!(p.as_ref(), "a".repeat(1025).as_bytes());
823        assert!(pages.take().is_none());
824
825        let p = BytePage::from(Bytes::copy_from_slice(b"123"));
826        assert_eq!(p.len(), 3);
827        assert!(!p.is_empty());
828        assert_eq!(p.as_ref(), b"123");
829        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
830
831        let p = BytePage::from(&b"123"[..]);
832        assert_eq!(p.len(), 3);
833        assert!(!p.is_empty());
834        assert_eq!(p.as_ref(), b"123");
835        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
836
837        let p = BytePage::from(b"123");
838        assert_eq!(p.len(), 3);
839        assert!(!p.is_empty());
840        assert_eq!(p.as_ref(), b"123");
841        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
842
843        let p = BytePage::from("123");
844        assert_eq!(p.len(), 3);
845        assert!(!p.is_empty());
846        assert_eq!(p.as_ref(), b"123");
847        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
848        assert_eq!(p.freeze(), b"123");
849
850        let p = BytePage::from(vec![b'1', b'2', b'3']);
851        assert_eq!(p.len(), 3);
852        assert!(!p.is_empty());
853        assert_eq!(p.as_ref(), b"123");
854        assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
855        assert_eq!(p.freeze(), b"123");
856
857        let mut p = BytePage::from(vec![b'1', b'2', b'3']);
858        p.advance_to(1);
859        assert_eq!(p.len(), 2);
860        assert!(!p.is_empty());
861        assert_eq!(p.as_ref(), b"23");
862
863        // debug
864        let mut pages = BytePages::new(BytePageSize::Size8);
865        pages.extend_from_slice(b"b");
866        assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
867        let p = pages.take().unwrap();
868        assert_eq!(p.as_ref(), b"b");
869
870        let mut pages = BytePages::new(BytePageSize::Size8);
871        pages.extend_from_slice(b"a");
872        pages.append(Bytes::copy_from_slice(b"123"));
873        pages.pages_mut().push_back(p);
874        assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
875
876        assert_eq!(pages.len(), 5);
877        pages.clear();
878        assert_eq!(pages.len(), 0);
879    }
880
881    #[test]
882    fn pages_copy_to() {
883        let mut pages = BytePages::default();
884        let mut pages2 = BytePages::default();
885        pages.put_slice(b"456");
886        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
887        pages.copy_to(&mut pages2);
888        let p = pages.freeze();
889        assert_eq!(p, b"123456");
890        let p2 = pages2.freeze();
891        assert_eq!(p2, b"123456");
892
893        let mut pages = BytePages::default();
894        let mut pages2 = BytePages::default();
895        pages.put_slice(b"456");
896        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
897        pages.copy_to(&mut pages2);
898        pages.put_u8(b'7');
899        let p = pages.freeze();
900        assert_eq!(p, b"1234567");
901        let p2 = pages2.freeze();
902        assert_eq!(p2, b"123456");
903
904        let mut pages = BytePages::default();
905        pages.put_slice(b"456");
906        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
907        let mut pages2 = pages.clone();
908        pages.put_u8(b'7');
909        let p = pages.freeze();
910        assert_eq!(p, b"1234567");
911        let p2 = pages2.freeze();
912        assert_eq!(p2, b"123456");
913    }
914
915    #[test]
916    fn pages_methods() {
917        // .split_to()
918        let mut pages = BytePages::default();
919        pages.put_slice(b"456");
920        pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
921        let mut pages2 = pages.split_to(1);
922        let p = pages.freeze();
923        assert_eq!(p, b"23456");
924        let p2 = pages2.freeze();
925        assert_eq!(p2, b"1");
926
927        let mut pages = BytePages::default();
928        pages.put_slice(b"456");
929        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
930        let mut pages2 = pages.split_to(4);
931        let p = pages.freeze();
932        assert_eq!(p, b"56");
933        let p2 = pages2.freeze();
934        assert_eq!(p2, b"1234");
935
936        // .split_into()
937        let mut pages = BytePages::default();
938        pages.put_slice(b"456");
939        pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
940        let mut pages2 = BytePages::default();
941        pages.split_into(1, &mut pages2);
942        let p = pages.freeze();
943        assert_eq!(p, b"23456");
944        let p2 = pages2.freeze();
945        assert_eq!(p2, b"1");
946
947        // .with_bytes_mut()
948        let mut pages = BytePages::default();
949        pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
950        assert_eq!(pages.len(), 3);
951        let p = pages.freeze();
952        assert_eq!(p, b"123");
953
954        let data = rand::rng()
955            .sample_iter(&rand::distr::Alphanumeric)
956            .take(65_536)
957            .map(char::from)
958            .collect::<String>();
959
960        let mut pages = BytePages::default();
961        pages.with_bytes_mut(|buf| buf.extend_from_slice(data.as_bytes()));
962        assert_eq!(pages.len(), 65_536);
963        let p = pages.freeze();
964        assert_eq!(p, data.as_bytes());
965
966        // into bytes
967        let page = BytePage::from(Bytes::copy_from_slice(b"123"));
968        assert_eq!(page, b"123");
969        assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
970        let b = Bytes::from(page);
971        assert_eq!(b, b"123");
972    }
973
974    #[test]
975    fn page_clone() {
976        // Bytes storage
977        let p = BytePage::from(Bytes::copy_from_slice(b"123"));
978        let p2 = p.clone();
979        assert_eq!(p, p2);
980
981        // StorageVec
982        let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
983        if let StorageType::Storage(ref mut st) = p.inner {
984            assert!(st.is_unique());
985        } else {
986            panic!()
987        }
988        let p2 = p.clone();
989        assert_eq!(p, p2);
990        if let StorageType::Storage(mut st) = p.inner {
991            assert!(!st.is_unique());
992        } else {
993            panic!()
994        }
995
996        // Vec<u8> storage
997        let p = BytePage::from(vec![b'1', b'2', b'3']);
998        let p2 = p.clone();
999        assert_eq!(p, p2);
1000        if let StorageType::Bytes(_) = p2.inner {
1001        } else {
1002            panic!()
1003        }
1004    }
1005
1006    #[test]
1007    fn page_split_to() {
1008        // Bytes storage
1009        let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1010        let p2 = p.split_to(1);
1011        assert_eq!(p, b"23");
1012        assert_eq!(p2, b"1");
1013
1014        // StorageVec
1015        let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1016        let p2 = p.split_to(1);
1017        assert_eq!(p, b"23");
1018        assert_eq!(p2, b"1");
1019
1020        // Vec<u8> storage
1021        let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1022        let p2 = p.split_to(1);
1023        assert_eq!(p, b"23");
1024        assert_eq!(p2, b"1");
1025    }
1026
1027    #[test]
1028    fn page_read() {
1029        use std::io::Read;
1030
1031        let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1032
1033        let mut buf = [0; 10];
1034        assert_eq!(page.read(&mut buf).unwrap(), 3);
1035        assert_eq!(page.len(), 0);
1036        assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1037    }
1038}