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