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, stvec::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    #[inline]
514    /// Returns a raw pointer to the data.
515    ///
516    /// # Safety
517    ///
518    /// One of the possible page storage types is `Bytes`.
519    /// A `Bytes` value may store its data inline, in which case `as_ptr()` returns
520    /// a pointer into the `Bytes` object itself. Moving the `BytePage` may
521    /// therefore invalidate the returned pointer.
522    pub unsafe fn as_ptr(&self) -> *const u8 {
523        unsafe {
524            match &self.inner {
525                StorageType::Bytes(b) => b.storage.as_ptr(),
526                StorageType::Storage(b) => b.as_ptr(),
527                StorageType::Vec(b) => b.as_ptr(),
528            }
529        }
530    }
531
532    /// Splits the buffer into two at the given index.
533    ///
534    /// Afterwards, `self` contains elements `[at, len)`, and the returned `BytePage`
535    /// contains elements `[0, at)`.
536    ///
537    /// Depending on the underlying storage, this operation might be `O(1)` or could
538    /// involve a memory copy.
539    #[must_use]
540    pub fn split_to(&mut self, at: usize) -> BytePage {
541        match &mut self.inner {
542            StorageType::Bytes(b) => {
543                let buf = b.split_to(cmp::min(at, b.len()));
544                BytePage {
545                    inner: StorageType::Bytes(buf),
546                }
547            }
548            StorageType::Storage(_) => {
549                let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
550                if let StorageType::Storage(st) = inner {
551                    self.inner = StorageType::Bytes(Bytes {
552                        storage: st.freeze(),
553                    });
554                    self.split_to(at)
555                } else {
556                    unreachable!()
557                }
558            }
559            StorageType::Vec(_) => {
560                let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
561                if let StorageType::Vec(b) = inner {
562                    self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
563                    self.split_to(at)
564                } else {
565                    unreachable!()
566                }
567            }
568        }
569    }
570
571    /// Advance the internal cursor.
572    ///
573    /// Afterwards `self` contains elements `[cnt, len)`.
574    /// This is an `O(1)` operation.
575    ///
576    /// # Panics
577    ///
578    /// Panics if `cnt > len`.
579    #[inline]
580    pub fn advance_to(&mut self, cnt: usize) {
581        match &mut self.inner {
582            StorageType::Bytes(b) => b.advance_to(cnt),
583            StorageType::Storage(b) => unsafe { b.set_start(cnt as u32) },
584            StorageType::Vec(b) => {
585                self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
586            }
587        }
588    }
589
590    /// Converts `self` into an immutable `Bytes`.
591    #[inline]
592    #[must_use]
593    pub fn freeze(self) -> Bytes {
594        match self.inner {
595            StorageType::Bytes(b) => b,
596            StorageType::Storage(st) => Bytes {
597                storage: st.freeze(),
598            },
599            StorageType::Vec(v) => Bytes::from(v),
600        }
601    }
602
603    fn into_storage(self) -> Result<StorageVec, Self> {
604        if let StorageType::Storage(mut st) = self.inner {
605            // SAFETY: Converting back to `StorageVec` requires uniqueness.
606            if !st.is_full() && st.is_unique() {
607                Ok(st)
608            } else {
609                Err(Self {
610                    inner: StorageType::Storage(st),
611                })
612            }
613        } else {
614            Err(self)
615        }
616    }
617}
618
619impl Clone for BytePage {
620    fn clone(&self) -> Self {
621        let inner = match &self.inner {
622            StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
623            StorageType::Storage(st) => {
624                // SAFETY: We garantee that `st` is not being used
625                // for modification. `st` is marked as non-unique after clone
626                StorageType::Storage(unsafe { st.clone() })
627            }
628            StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
629        };
630
631        Self { inner }
632    }
633}
634
635impl AsRef<[u8]> for BytePage {
636    #[inline]
637    fn as_ref(&self) -> &[u8] {
638        match &self.inner {
639            StorageType::Bytes(b) => b.as_ref(),
640            StorageType::Storage(b) => b.as_ref(),
641            StorageType::Vec(b) => b.as_ref(),
642        }
643    }
644}
645
646impl Borrow<[u8]> for BytePage {
647    #[inline]
648    fn borrow(&self) -> &[u8] {
649        self.as_ref()
650    }
651}
652
653impl From<Bytes> for BytePage {
654    fn from(buf: Bytes) -> Self {
655        BytePage {
656            inner: StorageType::Bytes(buf),
657        }
658    }
659}
660
661impl<'a> From<&'a Bytes> for BytePage {
662    fn from(buf: &'a Bytes) -> Self {
663        BytePage {
664            inner: StorageType::Bytes(buf.clone()),
665        }
666    }
667}
668
669impl From<BytesMut> for BytePage {
670    fn from(buf: BytesMut) -> Self {
671        BytePage {
672            inner: StorageType::Storage(buf.storage),
673        }
674    }
675}
676
677impl From<ByteString> for BytePage {
678    fn from(s: ByteString) -> Self {
679        s.into_bytes().into()
680    }
681}
682
683impl<'a> From<&'a ByteString> for BytePage {
684    fn from(s: &'a ByteString) -> Self {
685        s.clone().into_bytes().into()
686    }
687}
688
689impl From<StorageVec> for BytePage {
690    fn from(buf: StorageVec) -> Self {
691        BytePage {
692            inner: StorageType::Storage(buf),
693        }
694    }
695}
696
697impl From<Vec<u8>> for BytePage {
698    fn from(buf: Vec<u8>) -> Self {
699        BytePage {
700            inner: StorageType::Vec(buf),
701        }
702    }
703}
704
705impl From<&'static str> for BytePage {
706    fn from(buf: &'static str) -> Self {
707        BytePage::from(Bytes::from_static(buf.as_bytes()))
708    }
709}
710
711impl From<&'static [u8]> for BytePage {
712    fn from(buf: &'static [u8]) -> Self {
713        BytePage::from(Bytes::from_static(buf))
714    }
715}
716
717impl<const N: usize> From<&'static [u8; N]> for BytePage {
718    fn from(src: &'static [u8; N]) -> Self {
719        BytePage::from(Bytes::from_static(src))
720    }
721}
722
723impl From<BytePage> for Bytes {
724    fn from(page: BytePage) -> Self {
725        match page.inner {
726            StorageType::Bytes(b) => b,
727            StorageType::Storage(storage) => BytesMut { storage }.freeze(),
728            StorageType::Vec(v) => Bytes::copy_from_slice(&v),
729        }
730    }
731}
732
733impl From<BytePage> for BytesMut {
734    fn from(page: BytePage) -> Self {
735        match page.inner {
736            StorageType::Bytes(b) => b.into(),
737            StorageType::Storage(storage) => BytesMut { storage },
738            StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
739        }
740    }
741}
742
743impl PartialEq for BytePage {
744    fn eq(&self, other: &BytePage) -> bool {
745        self.as_ref() == other.as_ref()
746    }
747}
748
749impl<'a> PartialEq<&'a [u8]> for BytePage {
750    fn eq(&self, other: &&'a [u8]) -> bool {
751        self.as_ref() == *other
752    }
753}
754
755impl<'a, const N: usize> PartialEq<&'a [u8; N]> for BytePage {
756    fn eq(&self, other: &&'a [u8; N]) -> bool {
757        self.as_ref() == other.as_ref()
758    }
759}
760
761impl io::Read for BytePage {
762    fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
763        let len = cmp::min(self.len(), dst.len());
764        if len > 0 {
765            dst[..len].copy_from_slice(&self[..len]);
766            self.advance_to(len);
767        }
768        Ok(len)
769    }
770}
771
772impl ops::Deref for BytePage {
773    type Target = [u8];
774
775    #[inline]
776    fn deref(&self) -> &[u8] {
777        self.as_ref()
778    }
779}
780
781impl fmt::Debug for BytePage {
782    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
783        fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
784    }
785}
786
787#[cfg(test)]
788mod tests {
789    use rand::Rng;
790
791    use super::*;
792
793    #[test]
794    fn pages() {
795        unsafe {
796            // pages
797            let mut pages = BytePages::new(BytePageSize::Size8);
798            assert!(pages.is_empty());
799            assert_eq!(pages.len(), 0);
800            assert_eq!(pages.num_pages(), 0);
801            pages.extend_from_slice(b"b");
802            assert_eq!(pages.len(), 1);
803            assert_eq!(pages.num_pages(), 1);
804            pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
805            assert_eq!(pages.len(), 9217);
806            assert_eq!(pages.num_pages(), 2);
807            assert!(!pages.is_empty());
808
809            let mut pgs = BytePages::new(BytePageSize::Size8);
810            pgs.put_i8(b'a' as i8);
811            let p = pgs.take().unwrap();
812            assert_eq!(p.len(), 1);
813            assert_eq!(p.as_ref(), b"a");
814
815            pgs.extend_from_slice("a".repeat(8 * 1024 - 1).as_bytes());
816            assert_eq!(pgs.num_pages(), 1);
817            pgs.put_u8(b'a');
818            assert_eq!(pgs.num_pages(), 1);
819            assert!(pgs.current.is_none());
820
821            pgs.put_u8(b'a');
822            assert_eq!(pgs.num_pages(), 2);
823
824            pgs.append(Bytes::copy_from_slice("a".repeat(8 * 1024).as_bytes()));
825            assert_eq!(pgs.num_pages(), 3);
826            assert!(pgs.current.is_none());
827
828            // page
829            let p = pages.take().unwrap();
830            assert_eq!(p.len(), 8192);
831            let p = pages.take().unwrap();
832            assert_eq!(p.len(), 1025);
833            assert!(!p.is_empty());
834            assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
835            assert_eq!(p.as_ref(), "a".repeat(1025).as_bytes());
836            assert!(pages.take().is_none());
837
838            let p = BytePage::from(Bytes::copy_from_slice(b"123"));
839            assert_eq!(p.len(), 3);
840            assert!(!p.is_empty());
841            assert_eq!(p.as_ref(), b"123");
842            assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
843
844            let p = BytePage::from(&b"123"[..]);
845            assert_eq!(p.len(), 3);
846            assert!(!p.is_empty());
847            assert_eq!(p.as_ref(), b"123");
848            assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
849
850            let p = BytePage::from(b"123");
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
856            let p = BytePage::from("123");
857            assert_eq!(p.len(), 3);
858            assert!(!p.is_empty());
859            assert_eq!(p.as_ref(), b"123");
860            assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
861            assert_eq!(p.freeze(), b"123");
862
863            let p = BytePage::from(vec![b'1', b'2', b'3']);
864            assert_eq!(p.len(), 3);
865            assert!(!p.is_empty());
866            assert_eq!(p.as_ref(), b"123");
867            assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
868            assert_eq!(p.freeze(), b"123");
869
870            let mut p = BytePage::from(vec![b'1', b'2', b'3']);
871            p.advance_to(1);
872            assert_eq!(p.len(), 2);
873            assert!(!p.is_empty());
874            assert_eq!(p.as_ref(), b"23");
875
876            // debug
877            let mut pages = BytePages::new(BytePageSize::Size8);
878            pages.extend_from_slice(b"b");
879            assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
880            let p = pages.take().unwrap();
881            assert_eq!(p.as_ref(), b"b");
882
883            let mut pages = BytePages::new(BytePageSize::Size8);
884            pages.extend_from_slice(b"a");
885            pages.append(Bytes::copy_from_slice(b"123"));
886            pages.pages_mut().push_back(p);
887            assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
888
889            assert_eq!(pages.len(), 5);
890            pages.clear();
891            assert_eq!(pages.len(), 0);
892        }
893    }
894
895    #[test]
896    fn pages_copy_to() {
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        let p = pages.freeze();
903        assert_eq!(p, b"123456");
904        let p2 = pages2.freeze();
905        assert_eq!(p2, b"123456");
906
907        let mut pages = BytePages::default();
908        let mut pages2 = BytePages::default();
909        pages.put_slice(b"456");
910        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
911        pages.copy_to(&mut pages2);
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        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.clone();
922        pages.put_u8(b'7');
923        let p = pages.freeze();
924        assert_eq!(p, b"1234567");
925        let p2 = pages2.freeze();
926        assert_eq!(p2, b"123456");
927    }
928
929    #[test]
930    fn pages_methods() {
931        // .split_to()
932        let mut pages = BytePages::default();
933        pages.put_slice(b"456");
934        pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
935        let mut pages2 = pages.split_to(1);
936        let p = pages.freeze();
937        assert_eq!(p, b"23456");
938        let p2 = pages2.freeze();
939        assert_eq!(p2, b"1");
940
941        let mut pages = BytePages::default();
942        pages.put_slice(b"456");
943        pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
944        let mut pages2 = pages.split_to(4);
945        let p = pages.freeze();
946        assert_eq!(p, b"56");
947        let p2 = pages2.freeze();
948        assert_eq!(p2, b"1234");
949
950        // .split_into()
951        let mut pages = BytePages::default();
952        pages.put_slice(b"456");
953        pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
954        let mut pages2 = BytePages::default();
955        pages.split_into(1, &mut pages2);
956        let p = pages.freeze();
957        assert_eq!(p, b"23456");
958        let p2 = pages2.freeze();
959        assert_eq!(p2, b"1");
960
961        // .with_bytes_mut()
962        let mut pages = BytePages::default();
963        pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
964        assert_eq!(pages.len(), 3);
965        let p = pages.freeze();
966        assert_eq!(p, b"123");
967
968        let data = rand::rng()
969            .sample_iter(&rand::distr::Alphanumeric)
970            .take(65_536)
971            .map(char::from)
972            .collect::<String>();
973
974        let mut pages = BytePages::default();
975        pages.with_bytes_mut(|buf| buf.extend_from_slice(data.as_bytes()));
976        assert_eq!(pages.len(), 65_536);
977        let p = pages.freeze();
978        assert_eq!(p, data.as_bytes());
979
980        // into bytes
981        let page = BytePage::from(Bytes::copy_from_slice(b"123"));
982        assert_eq!(page, b"123");
983        assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
984        let b = Bytes::from(page);
985        assert_eq!(b, b"123");
986    }
987
988    #[test]
989    fn page_clone() {
990        // Bytes storage
991        let p = BytePage::from(Bytes::copy_from_slice(b"123"));
992        let p2 = p.clone();
993        assert_eq!(p, p2);
994
995        // StorageVec
996        let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
997        if let StorageType::Storage(ref mut st) = p.inner {
998            assert!(st.is_unique());
999        } else {
1000            panic!()
1001        }
1002        let p2 = p.clone();
1003        assert_eq!(p, p2);
1004        if let StorageType::Storage(mut st) = p.inner {
1005            assert!(!st.is_unique());
1006        } else {
1007            panic!()
1008        }
1009
1010        // Vec<u8> storage
1011        let p = BytePage::from(vec![b'1', b'2', b'3']);
1012        let p2 = p.clone();
1013        assert_eq!(p, p2);
1014        if let StorageType::Bytes(_) = p2.inner {
1015        } else {
1016            panic!()
1017        }
1018    }
1019
1020    #[test]
1021    fn page_split_to() {
1022        // Bytes storage
1023        let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1024        let p2 = p.split_to(1);
1025        assert_eq!(p, b"23");
1026        assert_eq!(p2, b"1");
1027
1028        // StorageVec
1029        let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1030        let p2 = p.split_to(1);
1031        assert_eq!(p, b"23");
1032        assert_eq!(p2, b"1");
1033
1034        // Vec<u8> storage
1035        let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1036        let p2 = p.split_to(1);
1037        assert_eq!(p, b"23");
1038        assert_eq!(p2, b"1");
1039    }
1040
1041    #[test]
1042    fn page_read() {
1043        use std::io::Read;
1044
1045        let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1046
1047        let mut buf = [0; 10];
1048        assert_eq!(page.read(&mut buf).unwrap(), 3);
1049        assert_eq!(page.len(), 0);
1050        assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1051    }
1052}