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