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 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 pub fn page_size(&self) -> BytePageSize {
62 self.st.as_ref().unwrap().size
63 }
64
65 pub fn set_page_size(&mut self, size: BytePageSize) {
67 self.st.as_mut().unwrap().size = size;
68 }
69
70 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 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 self.pages_mut().push_back(page);
102 }
103 }
104 } else {
105 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 pages.push_back(p);
112 }
113 }
114
115 #[inline]
116 pub fn extend_from_slice(&mut self, extend: &[u8]) {
122 self.put_slice(extend);
123 }
124
125 #[inline]
126 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 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 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 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 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 pub fn move_to(&mut self, pages: &mut BytePages) {
186 while let Some(page) = self.take() {
187 pages.append(page);
188 }
189 }
190
191 #[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 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 #[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 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 self.current.0 = buf.storage.0;
276 if buf.capacity() != cap {
277 buf.storage.unsize();
278 }
279 mem::forget(buf);
281
282 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 self.current.set_len(self.current.len() + cnt);
336 }
337
338 #[inline]
339 fn chunk_mut(&mut self) -> &mut UninitSlice {
340 unsafe {
341 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 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 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 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 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 #[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 #[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 #[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 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 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 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 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 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 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 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 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 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
913 let p2 = p.clone();
914 assert_eq!(p, p2);
915
916 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 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 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 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 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}