1#![allow(clippy::missing_panics_doc, clippy::box_collection)]
2use std::{borrow::Borrow, cell::Cell, cmp, collections::VecDeque, fmt, io, mem, ops};
3
4use crate::{Buf, BufMut, BytePageSize, ByteString, Bytes, BytesMut};
5use crate::{buf::UninitSlice, stvec::StorageVec};
6
7pub struct BytePages {
12 st: Option<Box<Inner>>,
13 current: Option<StorageVec>,
14}
15
16#[derive(Debug)]
17struct Inner {
18 size: BytePageSize,
19 len: usize,
21 pages: VecDeque<BytePage>,
22}
23
24thread_local! {
25 static CACHE: Cell<Option<Box<Vec<Box<Inner>>>>> = Cell::new(Some(Box::default()));
26}
27const CACHE_SIZE: usize = 128;
28
29const APPEND_COPY_LIMIT: usize = 4096;
31
32impl BytePages {
33 pub fn new(size: BytePageSize) -> Self {
43 assert!(size != BytePageSize::Unset, "Page size cannot be Unset");
44
45 let cached = CACHE
47 .try_with(|c| {
48 let mut cache = c.take()?;
49 let item = cache.pop();
50 c.set(Some(cache));
51 item
52 })
53 .ok()
54 .flatten();
55
56 let st = if let Some(mut item) = cached {
57 item.size = size;
58 item
59 } else {
60 Box::new(Inner {
61 size,
62 len: 0,
63 pages: VecDeque::with_capacity(8),
64 })
65 };
66
67 BytePages {
68 st: Some(st),
69 current: None,
70 }
71 }
72
73 fn pages(&self) -> &VecDeque<BytePage> {
74 &self.st.as_ref().unwrap().pages
75 }
76
77 fn push_front(&mut self, page: BytePage) {
80 let st = self.st.as_mut().unwrap();
81 st.len += page.len();
82 st.pages.push_front(page);
83 }
84
85 fn pop_front(&mut self) -> Option<BytePage> {
86 let st = self.st.as_mut().unwrap();
87 let page = st.pages.pop_front()?;
88 st.len -= page.len();
89 Some(page)
90 }
91
92 fn push_back(&mut self, page: BytePage) {
93 let st = self.st.as_mut().unwrap();
94 st.len += page.len();
95 st.pages.push_back(page);
96 }
97
98 pub fn page_size(&self) -> BytePageSize {
100 self.st.as_ref().unwrap().size
101 }
102
103 pub fn set_page_size(&mut self, size: BytePageSize) {
109 assert!(size != BytePageSize::Unset, "Page size cannot be Unset");
110 self.st.as_mut().unwrap().size = size;
111 }
112
113 pub fn prepend<T>(&mut self, buf: T) -> bool
117 where
118 BytePage: From<T>,
119 {
120 let p = BytePage::from(buf);
121 if p.is_empty() {
122 false
123 } else {
124 self.push_front(p);
125 true
126 }
127 }
128
129 pub fn append<T>(&mut self, buf: T)
139 where
140 BytePage: From<T>,
141 {
142 let p = BytePage::from(buf);
143 if !p.is_empty() {
144 if self.current_len() == 0 {
145 match p.into_storage() {
146 Ok(st) => {
147 self.current = Some(st);
148 }
149 Err(page) => {
150 self.push_back(page);
152 }
153 }
154 } else if p.len() <= APPEND_COPY_LIMIT {
155 self.put_slice(p.as_ref());
156 } else {
157 if let Some(st) = self.current.as_mut() {
159 let head = st.split_to(st.len());
160 self.push_back(<BytePage as From<Bytes>>::from(Bytes { storage: head }));
161 }
162 self.push_back(p);
163 }
164 }
165 }
166
167 #[inline]
168 pub fn extend_from_slice(&mut self, extend: &[u8]) {
174 self.put_slice(extend);
175 }
176
177 #[inline]
178 pub fn len(&self) -> usize {
180 self.st.as_ref().unwrap().len + self.current_len()
181 }
182
183 fn current_len(&self) -> usize {
184 self.current
185 .as_ref()
186 .map(StorageVec::len)
187 .unwrap_or_default()
188 }
189
190 fn spare(&self) -> usize {
192 self.current
193 .as_ref()
194 .map(StorageVec::remaining)
195 .unwrap_or_default()
196 }
197
198 #[inline]
199 pub fn is_empty(&self) -> bool {
201 self.len() == 0
202 }
203
204 #[inline]
205 pub fn num_pages(&self) -> usize {
207 if self.current_len() == 0 {
208 self.pages().len()
209 } else {
210 self.pages().len() + 1
211 }
212 }
213
214 pub fn take(&mut self) -> Option<BytePage> {
220 if let Some(page) = self.pop_front() {
221 Some(page)
222 } else if self.current_len() == 0 {
223 None
224 } else {
225 self.current.take().map(BytePage::from)
226 }
227 }
228
229 pub fn iter(&self) -> impl Iterator<Item = &[u8]> {
235 self.pages().iter().map(BytePage::as_ref).chain(
236 self.current
237 .as_ref()
238 .map(StorageVec::as_ref)
239 .filter(|s| !s.is_empty()),
240 )
241 }
242
243 pub fn advance_to(&mut self, mut cnt: usize) {
252 assert!(
253 cnt <= self.len(),
254 "cannot advance past the end of the buffer, cnt:{cnt} len:{}",
255 self.len()
256 );
257
258 while cnt > 0
259 && let Some(mut page) = self.pop_front()
260 {
261 if cnt < page.len() {
262 page.advance_to(cnt);
263 self.push_front(page);
264 return;
265 }
266 cnt -= page.len();
267 }
268 if cnt > 0
269 && let Some(st) = self.current.as_mut()
270 {
271 unsafe { st.set_start(cnt) };
273 }
274 }
275
276 #[inline]
277 pub fn copy_to(&self, pages: &mut BytePages) {
284 for p in self.pages() {
285 pages.append(p.clone());
286 }
287
288 if let Some(st) = &self.current {
289 pages.append(Bytes {
292 storage: st.shallow_freeze(),
293 });
294 }
295 }
296
297 pub fn move_to(&mut self, pages: &mut BytePages) {
305 if self.is_empty() {
306 return;
307 }
308
309 if let Some(st) = pages.current.as_mut()
310 && st.len() != 0
311 {
312 let head = st.split_to(st.len());
313 pages.push_back(<BytePage as From<Bytes>>::from(Bytes { storage: head }));
314 }
315
316 let src = self.st.as_mut().unwrap();
317 let dst = pages.st.as_mut().unwrap();
318 if dst.pages.is_empty() {
319 mem::swap(&mut src.pages, &mut dst.pages);
320 dst.len = mem::take(&mut src.len);
321 } else {
322 while let Some(page) = self.pop_front() {
323 pages.push_back(page);
324 }
325 }
326
327 if self.current_len() != 0
328 && let Some(st) = self.current.take()
329 {
330 pages.push_back(BytePage::from(st));
331 }
332 }
333
334 #[must_use]
346 pub fn split_to(&mut self, at: usize) -> BytePages {
347 let mut pages = BytePages::new(self.page_size());
348 self.split_into(at, &mut pages);
349 pages
350 }
351
352 pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
363 while let Some(mut page) = self.pop_front() {
364 let len = cmp::min(page.len(), at);
365 to.append(page.split_to(len));
366
367 if !page.is_empty() {
368 self.push_front(page);
369 return;
370 }
371 at -= len;
372 }
373 if at > 0
374 && let Some(mut st) = self.current.take()
375 {
376 if at < st.len() {
377 to.append(Bytes {
379 storage: st.split_to(at),
380 });
381 self.current = Some(st);
382 } else if st.len() == 0 {
383 self.current = Some(st);
384 } else {
385 to.append(BytePage::from(st));
386 }
387 }
388 }
389
390 #[inline]
392 pub fn clear(&mut self) {
393 while self.take().is_some() {}
394 }
395
396 #[inline]
398 #[must_use]
399 pub fn freeze(&mut self) -> Bytes {
400 let pages = self.num_pages();
401 if pages == 0 || self.is_empty() {
402 Bytes::new()
403 } else if pages == 1 {
404 self.take().unwrap().freeze()
405 } else {
406 let mut buf = BytesMut::with_capacity(self.len());
407 while let Some(p) = self.take() {
408 buf.extend_from_slice(&p);
409 }
410 buf.freeze()
411 }
412 }
413
414 #[inline]
415 pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
417 if self.pages().is_empty()
418 && self.current.is_none()
419 && let Some(st) = pages.current.take()
420 {
421 self.current = Some(st);
422 }
423 }
424
425 #[doc(hidden)]
435 #[deprecated(
436 since = "1.10.0",
437 note = "use the `BufMut` methods of `BytePages` instead"
438 )]
439 pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
440 where
441 F: FnOnce(&mut BytesMut) -> R,
442 {
443 let mut buf = BytesMut::new();
444 let res = f(&mut buf);
445 self.append(buf);
446 res
447 }
448
449 fn take_writable(&mut self) -> StorageVec {
454 match self.current.take() {
455 Some(st) if !st.is_full() => st,
456 Some(st) => {
457 if st.len() != 0 {
458 self.push_back(BytePage::from(st));
459 }
460 StorageVec::sized(self.page_size())
461 }
462 None => StorageVec::sized(self.page_size()),
463 }
464 }
465
466 fn with_current<F, R>(&mut self, f: F) -> R
467 where
468 F: FnOnce(&mut StorageVec) -> R,
469 {
470 let mut st = self.take_writable();
471 let result = f(&mut st);
472
473 if st.is_full() {
475 self.push_back(BytePage::from(st));
476 } else {
477 self.current = Some(st);
478 }
479
480 result
481 }
482}
483
484impl Drop for BytePages {
485 fn drop(&mut self) {
486 if let Some(mut st) = self.st.take() {
487 st.pages.clear();
488 st.pages.shrink_to(8);
490 st.len = 0;
491 let _ = CACHE.try_with(move |c| {
493 if let Some(mut cache) = c.take() {
494 if cache.len() < CACHE_SIZE {
495 cache.push(st);
496 }
497 c.set(Some(cache));
498 }
499 });
500 }
501 }
502}
503
504impl fmt::Debug for BytePages {
505 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
506 let mut f = fmt.debug_tuple("BytePages");
507 for p in self.pages() {
508 f.field(p);
509 }
510 if let Some(st) = &self.current {
511 f.field(&crate::debug::BsDebug(st.as_ref()));
512 }
513 f.finish()
514 }
515}
516
517impl Default for BytePages {
518 fn default() -> Self {
519 BytePages::new(BytePageSize::Size16)
520 }
521}
522
523impl BufMut for BytePages {
527 #[inline]
528 fn remaining_mut(&self) -> usize {
529 usize::MAX - self.len()
530 }
531
532 #[inline]
533 unsafe fn advance_mut(&mut self, cnt: usize) {
534 if cnt == 0 {
535 return;
536 }
537 let spare = self.spare();
538 assert!(
539 cnt <= spare,
540 "cannot advance past the current page: {cnt:?} <= {spare:?}"
541 );
542 let st = self.current.as_mut().unwrap();
543 st.set_len(st.len() + cnt);
544 }
545
546 #[inline]
547 fn chunk_mut(&mut self) -> &mut UninitSlice {
548 let st = self.take_writable();
549 self.current.insert(st).spare_mut()
550 }
551
552 fn put<T: Buf>(&mut self, mut src: T)
553 where
554 Self: Sized,
555 {
556 while src.has_remaining() {
557 let chunk = src.chunk();
558 let len = chunk.len();
559 self.put_slice(chunk);
560 src.advance(len);
561 }
562 }
563
564 #[inline]
565 fn put_slice(&mut self, src: &[u8]) {
566 if let Some(st) = self.current.as_mut()
568 && st.remaining() > src.len()
569 {
570 st.put_slice_partial(src);
571 } else {
572 self.put_slice_pages(src);
573 }
574 }
575
576 #[inline]
577 fn put_u8(&mut self, n: u8) {
578 self.with_current(|st| st.put_u8(n));
579 }
580
581 #[inline]
582 fn put_i8(&mut self, n: i8) {
583 self.put_u8(n as u8);
584 }
585}
586
587impl BytePages {
588 fn put_slice_pages(&mut self, mut src: &[u8]) {
589 while !src.is_empty() {
590 let amount = self.with_current(|st| st.put_slice_partial(src));
591
592 src = &src[amount..];
593 }
594 }
595}
596
597impl Clone for BytePages {
598 fn clone(&self) -> Self {
599 let size = self.page_size();
600 let mut pages = BytePages::new(size);
601 self.copy_to(&mut pages);
602 pages
603 }
604}
605
606impl io::Write for BytePages {
607 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
608 self.put_slice(src);
609 Ok(src.len())
610 }
611
612 fn flush(&mut self) -> Result<(), io::Error> {
613 Ok(())
614 }
615}
616
617impl From<BytePages> for Bytes {
618 fn from(mut pages: BytePages) -> Bytes {
620 pages.freeze()
621 }
622}
623
624impl From<BytePages> for BytesMut {
625 fn from(mut pages: BytePages) -> BytesMut {
628 if pages.num_pages() == 1 {
629 return BytesMut::from(pages.take().unwrap());
630 }
631
632 let mut buf = BytesMut::with_capacity(pages.len());
633 while let Some(p) = pages.take() {
634 buf.extend_from_slice(&p);
635 }
636 buf
637 }
638}
639
640pub struct BytePage {
642 inner: StorageType,
643}
644
645enum StorageType {
646 Bytes(Bytes),
647 Storage(StorageVec),
648 Vec(Vec<u8>),
649}
650
651impl BytePage {
652 #[inline]
653 pub fn len(&self) -> usize {
655 self.as_ref().len()
656 }
657
658 #[inline]
659 pub fn is_empty(&self) -> bool {
661 self.len() == 0
662 }
663
664 #[inline]
665 pub unsafe fn as_ptr(&self) -> *const u8 {
674 unsafe {
677 match &self.inner {
678 StorageType::Bytes(b) => b.storage.as_ptr(),
679 StorageType::Storage(b) => b.as_ptr(),
680 StorageType::Vec(b) => b.as_ptr(),
681 }
682 }
683 }
684
685 #[inline]
686 #[doc(hidden)]
687 pub fn info(&self) -> crate::info::PageKind {
689 match &self.inner {
690 StorageType::Bytes(_) => crate::info::PageKind::Bytes,
691 StorageType::Storage(_) => crate::info::PageKind::Storage,
692 StorageType::Vec(_) => crate::info::PageKind::Vec,
693 }
694 }
695
696 #[inline]
697 #[doc(hidden)]
698 pub fn is_inline(&self) -> bool {
703 matches!(&self.inner, StorageType::Bytes(b) if b.is_inline())
704 }
705
706 #[must_use]
718 pub fn split_to(&mut self, at: usize) -> BytePage {
719 match &mut self.inner {
720 StorageType::Bytes(b) => {
721 let buf = b.split_to(cmp::min(at, b.len()));
722 BytePage {
723 inner: StorageType::Bytes(buf),
724 }
725 }
726 StorageType::Storage(_) => {
727 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
728 if let StorageType::Storage(st) = inner {
729 self.inner = StorageType::Bytes(Bytes {
730 storage: st.freeze(),
731 });
732 self.split_to(at)
733 } else {
734 unreachable!()
735 }
736 }
737 StorageType::Vec(_) => {
738 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
739 if let StorageType::Vec(b) = inner {
740 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
741 self.split_to(at)
742 } else {
743 unreachable!()
744 }
745 }
746 }
747 }
748
749 #[inline]
759 pub fn advance_to(&mut self, cnt: usize) {
760 match &mut self.inner {
761 StorageType::Bytes(b) => b.advance_to(cnt),
762 StorageType::Storage(b) => unsafe { b.set_start(cnt) },
765 StorageType::Vec(b) => {
766 assert!(
767 cnt <= b.len(),
768 "cannot advance past the end of the buffer, cnt:{cnt} len:{}",
769 b.len()
770 );
771 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
772 }
773 }
774 }
775
776 #[inline]
778 #[must_use]
779 pub fn freeze(self) -> Bytes {
780 match self.inner {
781 StorageType::Bytes(b) => b,
782 StorageType::Storage(st) => Bytes {
783 storage: st.freeze(),
784 },
785 StorageType::Vec(v) => Bytes::from(v),
786 }
787 }
788
789 fn into_storage(self) -> Result<StorageVec, Self> {
790 if let StorageType::Storage(st) = self.inner {
791 if !st.is_full() && st.is_unique() {
793 Ok(st)
794 } else {
795 Err(Self {
796 inner: StorageType::Storage(st),
797 })
798 }
799 } else {
800 Err(self)
801 }
802 }
803}
804
805impl Clone for BytePage {
806 fn clone(&self) -> Self {
807 let inner = match &self.inner {
808 StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
809 StorageType::Storage(st) => StorageType::Bytes(Bytes {
812 storage: st.shallow_freeze(),
813 }),
814 StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
815 };
816
817 Self { inner }
818 }
819}
820
821impl AsRef<[u8]> for BytePage {
822 #[inline]
823 fn as_ref(&self) -> &[u8] {
824 match &self.inner {
825 StorageType::Bytes(b) => b.as_ref(),
826 StorageType::Storage(b) => b.as_ref(),
827 StorageType::Vec(b) => b.as_ref(),
828 }
829 }
830}
831
832impl Borrow<[u8]> for BytePage {
833 #[inline]
834 fn borrow(&self) -> &[u8] {
835 self.as_ref()
836 }
837}
838
839impl From<Bytes> for BytePage {
840 fn from(buf: Bytes) -> Self {
841 BytePage {
842 inner: StorageType::Bytes(buf),
843 }
844 }
845}
846
847impl<'a> From<&'a Bytes> for BytePage {
848 fn from(buf: &'a Bytes) -> Self {
849 BytePage {
850 inner: StorageType::Bytes(buf.clone()),
851 }
852 }
853}
854
855impl From<BytesMut> for BytePage {
856 fn from(buf: BytesMut) -> Self {
857 BytePage {
858 inner: StorageType::Storage(buf.storage),
859 }
860 }
861}
862
863impl From<ByteString> for BytePage {
864 fn from(s: ByteString) -> Self {
865 s.into_bytes().into()
866 }
867}
868
869impl<'a> From<&'a ByteString> for BytePage {
870 fn from(s: &'a ByteString) -> Self {
871 s.clone().into_bytes().into()
872 }
873}
874
875impl From<StorageVec> for BytePage {
876 fn from(buf: StorageVec) -> Self {
877 BytePage {
878 inner: StorageType::Storage(buf),
879 }
880 }
881}
882
883impl From<Vec<u8>> for BytePage {
884 fn from(buf: Vec<u8>) -> Self {
885 BytePage {
886 inner: StorageType::Vec(buf),
887 }
888 }
889}
890
891impl From<&'static str> for BytePage {
892 fn from(buf: &'static str) -> Self {
893 Bytes::from_static(buf.as_bytes()).into()
894 }
895}
896
897impl From<&'static [u8]> for BytePage {
898 fn from(buf: &'static [u8]) -> Self {
899 Bytes::from_static(buf).into()
900 }
901}
902
903impl<const N: usize> From<&'static [u8; N]> for BytePage {
904 fn from(buf: &'static [u8; N]) -> Self {
905 Bytes::from_static(buf).into()
906 }
907}
908
909impl From<BytePage> for Bytes {
910 fn from(page: BytePage) -> Self {
911 match page.inner {
912 StorageType::Bytes(b) => b,
913 StorageType::Storage(storage) => BytesMut { storage }.freeze(),
914 StorageType::Vec(v) => Bytes::copy_from_slice(&v),
915 }
916 }
917}
918
919impl From<BytePage> for BytesMut {
920 fn from(page: BytePage) -> Self {
921 match page.inner {
922 StorageType::Bytes(b) => b.into(),
923 StorageType::Storage(storage) => {
925 if storage.is_unique() {
926 BytesMut { storage }
927 } else {
928 BytesMut::copy_from_slice(storage.as_ref())
929 }
930 }
931 StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
932 }
933 }
934}
935
936impl PartialEq for BytePage {
937 fn eq(&self, other: &BytePage) -> bool {
938 self.as_ref() == other.as_ref()
939 }
940}
941
942impl_partial_eq!(BytePage);
943
944impl_read!(BytePage);
945
946impl ops::Deref for BytePage {
947 type Target = [u8];
948
949 #[inline]
950 fn deref(&self) -> &[u8] {
951 self.as_ref()
952 }
953}
954
955impl fmt::Debug for BytePage {
956 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
957 fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
958 }
959}
960
961#[cfg(test)]
962mod tests {
963 use rand::Rng;
964
965 use super::*;
966
967 #[test]
973 #[allow(clippy::op_ref, clippy::cmp_owned)]
974 fn page_eq_and_read() {
975 use std::io::Read;
976
977 let mut page = BytePage::from(Vec::from(&b"hello"[..]));
978 assert_eq!(page, b"hello"[..]);
979 assert_eq!(page, *b"hello");
980 assert_eq!(page, b"hello");
981 assert_eq!(page, &b"hello"[..]);
982 assert_eq!(page, "hello");
983 assert_eq!(page, *"hello");
984 assert_eq!(page, b"hello".to_vec());
985 assert_eq!(page, String::from("hello"));
986 assert_eq!(b"hello"[..], page);
987 assert_eq!(*b"hello", page);
988 assert_eq!(b"hello", page);
989 assert_eq!(&b"hello"[..], page);
990 assert_eq!("hello", page);
991 assert_eq!(*"hello", page);
992 assert_eq!(b"hello".to_vec(), page);
993 assert_eq!(String::from("hello"), page);
994 assert_ne!(page, "hell");
995
996 let mut buf = [0u8; 3];
997 assert_eq!(page.read(&mut buf).unwrap(), 3);
998 assert_eq!(&buf, b"hel");
999 assert_eq!(page, "lo");
1000 assert_eq!(page.read(&mut buf).unwrap(), 2);
1001 assert_eq!(page.read(&mut buf).unwrap(), 0);
1002 assert!(page.is_empty());
1003 }
1004
1005 #[test]
1011 fn page_info() {
1012 use crate::info::PageKind;
1013
1014 let p = BytePage::from(Bytes::copy_from_slice(&[1; 64]));
1015 assert_eq!(p.info(), PageKind::Bytes);
1016 let p = BytePage::from(BytesMut::copy_from_slice(&[1; 64][..]));
1017 assert_eq!(p.info(), PageKind::Storage);
1018 let p = BytePage::from(vec![1; 64]);
1019 assert_eq!(p.info(), PageKind::Vec);
1020 assert!(!p.is_inline());
1021
1022 assert!(BytePage::from(Bytes::copy_from_slice(&[1; 4])).is_inline());
1023 assert!(!BytePage::from(Bytes::copy_from_slice(&[1; 64])).is_inline());
1024 assert!(!BytePage::from(BytesMut::copy_from_slice(&[1; 4][..])).is_inline());
1025 }
1026
1027 #[test]
1033 fn append_copies_small_and_splits_for_large() {
1034 let cap = BytePageSize::Size16.capacity();
1035 let mut pages = BytePages::new(BytePageSize::Size16);
1036 pages.extend_from_slice(b"head\r\n");
1037
1038 pages.append(Bytes::copy_from_slice(&[1; APPEND_COPY_LIMIT]));
1040 assert_eq!(pages.num_pages(), 1);
1041 assert_eq!(pages.current_len(), 6 + APPEND_COPY_LIMIT);
1042
1043 let body = Bytes::copy_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1045 let body_ptr = body.as_ptr();
1046 pages.append(body.clone());
1047 assert_eq!(pages.num_pages(), 2);
1048 assert_eq!(pages.current_len(), 0);
1049 assert_eq!(pages.spare(), cap - 6 - APPEND_COPY_LIMIT);
1050
1051 let page_ptr = pages.pages()[0].as_ref().as_ptr();
1053 pages.extend_from_slice(b"\r\n");
1054 assert_eq!(pages.num_pages(), 3);
1055 let tail_ptr = pages.current.as_ref().unwrap().as_ref().as_ptr();
1056 assert_eq!(tail_ptr, page_ptr.wrapping_add(6 + APPEND_COPY_LIMIT));
1057
1058 let mut expected = b"head\r\n".to_vec();
1059 expected.extend_from_slice(&[1; APPEND_COPY_LIMIT]);
1060 expected.extend_from_slice(&body);
1061 expected.extend_from_slice(b"\r\n");
1062 assert_eq!(pages.len(), expected.len());
1063
1064 let first = pages.take().unwrap();
1065 let second = pages.take().unwrap();
1066 assert_eq!(second.as_ref().as_ptr(), body_ptr);
1067 let third = pages.take().unwrap();
1068 assert!(pages.take().is_none());
1069 let data = [first.as_ref(), second.as_ref(), third.as_ref()].concat();
1070 assert_eq!(data, expected);
1071
1072 pages.extend_from_slice(b"x");
1074 pages.append(body);
1075 assert_eq!(pages.take().unwrap().as_ref(), b"x");
1076 assert_eq!(pages.take().unwrap().len(), APPEND_COPY_LIMIT + 1);
1077 assert!(pages.take().is_none());
1078 assert_eq!(pages.num_pages(), 0);
1079 assert_eq!(pages.spare(), cap - 1);
1080 }
1081
1082 #[test]
1088 fn pages() {
1089 let cap = BytePageSize::Size8.capacity();
1090 unsafe {
1093 let mut pages = BytePages::new(BytePageSize::Size8);
1095 assert!(pages.is_empty());
1096 assert_eq!(pages.len(), 0);
1097 assert_eq!(pages.num_pages(), 0);
1098 pages.extend_from_slice(b"b");
1099 assert_eq!(pages.len(), 1);
1100 assert_eq!(pages.num_pages(), 1);
1101 pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
1102 assert_eq!(pages.len(), 9217);
1103 assert_eq!(pages.num_pages(), 2);
1104 assert!(!pages.is_empty());
1105
1106 let mut pgs = BytePages::new(BytePageSize::Size8);
1107 pgs.put_i8(b'a' as i8);
1108 let p = pgs.take().unwrap();
1109 assert_eq!(p.len(), 1);
1110 assert_eq!(p.as_ref(), b"a");
1111
1112 pgs.extend_from_slice("a".repeat(cap - 1).as_bytes());
1113 assert_eq!(pgs.num_pages(), 1);
1114 pgs.put_u8(b'a');
1115 assert_eq!(pgs.num_pages(), 1);
1116 assert!(pgs.current.is_none());
1117
1118 pgs.put_u8(b'a');
1119 assert_eq!(pgs.num_pages(), 2);
1120
1121 pgs.append(Bytes::copy_from_slice("a".repeat(cap).as_bytes()));
1122 assert_eq!(pgs.num_pages(), 3);
1123 assert_eq!(pgs.current_len(), 0);
1124 assert_eq!(pgs.spare(), cap - 1);
1125
1126 let p = pages.take().unwrap();
1128 assert_eq!(p.len(), cap);
1129 let p = pages.take().unwrap();
1130 assert_eq!(p.len(), 9217 - cap);
1131 assert!(!p.is_empty());
1132 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1133 assert_eq!(p.as_ref(), "a".repeat(9217 - cap).as_bytes());
1134 assert!(pages.take().is_none());
1135
1136 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1137 assert_eq!(p.len(), 3);
1138 assert!(!p.is_empty());
1139 assert_eq!(p.as_ref(), b"123");
1140 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1141
1142 let p = BytePage::from(&b"123"[..]);
1143 assert_eq!(p.len(), 3);
1144 assert!(!p.is_empty());
1145 assert_eq!(p.as_ref(), b"123");
1146 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1147
1148 let p = BytePage::from(b"123");
1149 assert_eq!(p.len(), 3);
1150 assert!(!p.is_empty());
1151 assert_eq!(p.as_ref(), b"123");
1152 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1153
1154 let p = BytePage::from("123");
1155 assert_eq!(p.len(), 3);
1156 assert!(!p.is_empty());
1157 assert_eq!(p.as_ref(), b"123");
1158 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1159 assert_eq!(p.freeze(), b"123");
1160
1161 let p = BytePage::from(vec![b'1', b'2', b'3']);
1162 assert_eq!(p.len(), 3);
1163 assert!(!p.is_empty());
1164 assert_eq!(p.as_ref(), b"123");
1165 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1166 assert_eq!(p.freeze(), b"123");
1167
1168 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1169 p.advance_to(1);
1170 assert_eq!(p.len(), 2);
1171 assert!(!p.is_empty());
1172 assert_eq!(p.as_ref(), b"23");
1173
1174 let mut pages = BytePages::new(BytePageSize::Size8);
1176 pages.extend_from_slice(b"b");
1177 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
1178 let p = pages.take().unwrap();
1179 assert_eq!(p.as_ref(), b"b");
1180
1181 let mut pages = BytePages::new(BytePageSize::Size8);
1182 pages.extend_from_slice(b"a");
1183 pages.append(Bytes::copy_from_slice(b"123"));
1184 pages.push_back(p);
1185 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
1186
1187 assert_eq!(pages.len(), 5);
1188 pages.clear();
1189 assert_eq!(pages.len(), 0);
1190 }
1191 }
1192
1193 fn assert_len(pages: &BytePages) {
1195 let len = pages.pages().iter().map(BytePage::len).sum::<usize>() + pages.current_len();
1196 assert_eq!(pages.len(), len);
1197 assert_eq!(pages.is_empty(), len == 0);
1198 }
1199
1200 #[test]
1206 fn pages_len_tracking() {
1207 let mut rng = rand::rng();
1208 let mut pages = BytePages::new(BytePageSize::Size8);
1209 let mut other = BytePages::new(BytePageSize::Size8);
1210 let mut expected = 0;
1211
1212 let (iters, max) = if cfg!(miri) { (100, 256) } else { (2000, 12 * 1024) };
1213 for _ in 0..iters {
1214 let n = rng.random_range(0..max);
1215 match rng.random_range(0..9) {
1216 0 => {
1217 pages.extend_from_slice(&vec![1; n]);
1218 expected += n;
1219 }
1220 1 => {
1221 pages.append(Bytes::copy_from_slice(&vec![2; n]));
1222 expected += n;
1223 }
1224 2 => {
1225 if pages.prepend(BytesMut::copy_from_slice(vec![3; n])) {
1226 expected += n;
1227 }
1228 }
1229 3 => {
1230 if let Some(p) = pages.take() {
1231 expected -= p.len();
1232 }
1233 }
1234 4 => {
1235 let at = cmp::min(n, expected);
1236 let split = pages.split_to(at);
1237 assert_len(&split);
1238 assert_eq!(split.len(), at);
1239 expected -= at;
1240 }
1241 5 => {
1242 let at = cmp::min(n, expected);
1243 pages.split_into(at, &mut other);
1244 expected -= at;
1245 }
1246 6 => {
1247 other.move_to(&mut pages);
1248 assert_len(&other);
1249 assert!(other.is_empty());
1250 expected = pages.len();
1251 }
1252 7 => {
1253 let mut copy = BytePages::new(BytePageSize::Size8);
1254 pages.copy_to(&mut copy);
1255 assert_len(©);
1256 assert_eq!(copy.len(), expected);
1257 }
1258 _ => {
1259 pages.put_u8(4);
1260 expected += 1;
1261 }
1262 }
1263 assert_len(&pages);
1264 assert_len(&other);
1265 assert_eq!(pages.len(), expected);
1266 }
1267
1268 let len = pages.len();
1269 assert_eq!(pages.freeze().len(), len);
1270 assert_len(&pages);
1271 assert!(pages.is_empty());
1272 pages.extend_from_slice(b"123");
1273 pages.clear();
1274 assert_len(&pages);
1275 assert!(pages.is_empty());
1276 }
1277
1278 #[test]
1283 fn pages_len_after_cache_reuse() {
1284 let mut pages = BytePages::new(BytePageSize::Size8);
1285 pages.append(Bytes::copy_from_slice(&[1; 64]));
1286 pages.append(Bytes::copy_from_slice(&[1; 64]));
1287 drop(pages);
1288
1289 let pages = BytePages::new(BytePageSize::Size8);
1290 assert_len(&pages);
1291 assert!(pages.is_empty());
1292 }
1293
1294 #[test]
1300 fn pages_copy_to_shares_current() {
1301 let mut pages = BytePages::new(BytePageSize::Size8);
1302 pages.put_slice(&[1; 64]);
1303 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1306
1307 let mut copy = BytePages::new(BytePageSize::Size8);
1308 pages.copy_to(&mut copy);
1309 let page = copy.take().unwrap();
1310 assert_eq!(unsafe { page.as_ptr() }, ptr.cast_const());
1312 assert_eq!(page.as_ref(), &[1; 64][..]);
1313
1314 pages.put_slice(&[2; 64]);
1316 assert_eq!(unsafe { pages.current.as_ref().unwrap().as_ptr() }, ptr);
1319 assert_eq!(page.as_ref(), &[1; 64][..]);
1320 assert_eq!(pages.len(), 128);
1321
1322 drop(pages);
1323 assert_eq!(page.as_ref(), &[1; 64][..]);
1324 }
1325
1326 #[test]
1332 fn pages_split_keeps_current_writable() {
1333 let mut pages = BytePages::new(BytePageSize::Size8);
1334 pages.put_slice(&[1; 64]);
1335 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1338 let remaining = pages.spare();
1339
1340 let mut head = pages.split_to(40);
1341 assert_eq!(head.len(), 40);
1342 assert_eq!(pages.len(), 24);
1343 assert_eq!(pages.num_pages(), 1);
1344 assert_eq!(pages.spare(), remaining);
1345
1346 pages.put_slice(&[2; 16]);
1348 assert_eq!(pages.num_pages(), 1);
1349 assert_eq!(
1350 unsafe { pages.current.as_ref().unwrap().as_ptr() },
1353 ptr.wrapping_add(40)
1354 );
1355 let mut expected = vec![1; 24];
1356 expected.extend_from_slice(&[2; 16]);
1357 assert_eq!(&pages.freeze()[..], &expected[..]);
1358 assert_eq!(&head.freeze()[..], &[1; 40][..]);
1359
1360 let mut pages = BytePages::new(BytePageSize::Size8);
1362 pages.put_slice(&[1; 64]);
1363 let mut to = BytePages::new(BytePageSize::Size8);
1364 pages.split_into(2, &mut to);
1365 assert_eq!(&to.freeze()[..], &[1; 2][..]);
1366 assert_eq!(pages.spare(), remaining);
1367 assert_eq!(pages.len(), 62);
1368
1369 let mut pages = BytePages::new(BytePageSize::Size8);
1371 pages.put_slice(&[1; 64]);
1372 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1375 let to = pages.split_to(64);
1376 assert!(pages.is_empty());
1377 assert_eq!(pages.num_pages(), 0);
1378 assert_eq!(to.spare(), remaining);
1379 assert_eq!(unsafe { to.current.as_ref().unwrap().as_ptr() }, ptr);
1382
1383 let mut pages = BytePages::new(BytePageSize::Size8);
1385 let _ = pages.chunk_mut();
1386 let head = pages.split_to(10);
1387 assert!(head.is_empty());
1388 assert_eq!(pages.spare(), remaining + 64);
1389 }
1390
1391 #[test]
1397 fn pages_buf_mut_grows() {
1398 let mut pages = BytePages::new(BytePageSize::Size8);
1399 assert!(pages.has_remaining_mut());
1400 assert_eq!(pages.remaining_mut(), usize::MAX);
1401 unsafe { pages.advance_mut(0) };
1403
1404 let n = pages.chunk_mut().len();
1406 unsafe {
1409 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1410 pages.advance_mut(n);
1411 }
1412 assert!(pages.chunk_mut().len() > 0);
1413 assert_eq!(pages.num_pages(), 1);
1415 unsafe {
1418 *pages.chunk_mut().as_mut_ptr() = 2;
1419 pages.advance_mut(1);
1420 }
1421 assert_eq!(pages.len(), n + 1);
1422 assert_eq!(pages.remaining_mut(), usize::MAX - n - 1);
1423
1424 let mut pages = BytePages::new(BytePageSize::Size8);
1426 pages.put(&[3u8; 200][..]);
1427 pages.put(Bytes::from_static(b"abcd"));
1428 io::Write::write_all(&mut pages, &[4; 100]).unwrap();
1429 let mut expected = vec![3; 200];
1430 expected.extend_from_slice(b"abcd");
1431 expected.extend_from_slice(&[4; 100]);
1432 assert_eq!(&pages.freeze()[..], &expected[..]);
1433 }
1434
1435 #[test]
1441 fn pages_byte_write_after_full_page() {
1442 let mut pages = BytePages::new(BytePageSize::Size8);
1444 let n = pages.chunk_mut().len();
1445 unsafe {
1448 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1449 pages.advance_mut(n);
1450 }
1451 pages.put_u8(2);
1452 pages.put_i8(3);
1453 assert_eq!(pages.num_pages(), 2);
1454 assert_eq!(pages.pages()[0].len(), n);
1455 let mut expected = vec![1; n];
1456 expected.extend_from_slice(&[2, 3]);
1457 assert_eq!(&pages.freeze()[..], &expected[..]);
1458
1459 let mut pages = BytePages::new(BytePageSize::Size8);
1461 let n = pages.chunk_mut().len();
1462 unsafe {
1465 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1466 pages.advance_mut(n);
1467 }
1468 pages.append(vec![2; APPEND_COPY_LIMIT + 1]);
1469 pages.put_u8(3);
1470 assert!(pages.pages().iter().all(|p| !p.is_empty()));
1471 let mut expected = vec![1; n];
1472 expected.extend_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1473 expected.push(3);
1474 assert_eq!(&pages.freeze()[..], &expected[..]);
1475 }
1476
1477 #[test]
1482 #[should_panic(expected = "cannot advance past the current page")]
1483 fn pages_advance_past_current_page() {
1484 let mut pages = BytePages::new(BytePageSize::Size8);
1485 let n = pages.chunk_mut().len();
1486 unsafe { pages.advance_mut(n + 1) };
1489 }
1490
1491 #[test]
1496 #[should_panic(expected = "Page size cannot be Unset")]
1497 fn pages_new_unset() {
1498 let _ = BytePages::new(BytePageSize::Unset);
1499 }
1500
1501 #[test]
1506 #[should_panic(expected = "Page size cannot be Unset")]
1507 fn pages_set_page_size_unset() {
1508 let mut pages = BytePages::new(BytePageSize::Size8);
1509 pages.set_page_size(BytePageSize::Unset);
1510 }
1511
1512 #[test]
1517 fn cached_pages_list_is_shrunk() {
1518 let mut pages = BytePages::new(BytePageSize::Size4);
1519 for _ in 0..200 {
1520 pages.append(Bytes::from_static(b"page"));
1521 }
1522 assert!(pages.pages().capacity() >= 200);
1523 drop(pages);
1524
1525 let pages = BytePages::new(BytePageSize::Size4);
1526 assert!(
1527 pages.pages().capacity() < 200,
1528 "{}",
1529 pages.pages().capacity()
1530 );
1531 }
1532
1533 #[test]
1539 fn pages_into_bytes_single_page() {
1540 let mut pages = BytePages::new(BytePageSize::Size8);
1542 pages.put_slice(&[1; 64]);
1543 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1546 let mut buf = BytesMut::from(pages);
1547 assert_eq!(buf.as_ptr(), ptr.cast_const());
1548 assert_eq!(&buf[..], &[1; 64][..]);
1549 assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
1551 buf.extend_from_slice(&[2; 64]);
1552 assert_eq!(buf.as_ptr(), ptr.cast_const());
1553
1554 let mut pages = BytePages::new(BytePageSize::Size8);
1555 pages.put_slice(&[1; 64]);
1556 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1559 let b = Bytes::from(pages);
1560 assert_eq!(b.as_ptr(), ptr.cast_const());
1561 assert_eq!(&b[..], &[1; 64][..]);
1562
1563 let src = Bytes::copy_from_slice(&[3; 64]);
1565 let ptr = src.as_ptr();
1566 let mut pages = BytePages::new(BytePageSize::Size8);
1567 pages.prepend(src);
1568 assert_eq!(BytesMut::from(pages).as_ptr(), ptr);
1569
1570 let src = Bytes::copy_from_slice(&[3; 64]);
1572 let mut pages = BytePages::new(BytePageSize::Size8);
1573 pages.prepend(&src);
1574 let mut buf = BytesMut::from(pages);
1575 assert_ne!(buf.as_ptr(), src.as_ptr());
1576 buf[0] = 4;
1577 assert_eq!(&src[..], &[3; 64][..]);
1578 }
1579
1580 #[test]
1586 fn pages_into_bytes_multiple_pages() {
1587 let mut pages = BytePages::new(BytePageSize::Size8);
1588 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1589 pages.put_slice(&[2; 64]);
1590 assert_eq!(pages.num_pages(), 2);
1591 let buf = BytesMut::from(pages);
1592 assert_eq!(&buf[..64], &[1; 64][..]);
1593 assert_eq!(&buf[64..], &[2; 64][..]);
1594
1595 let mut pages = BytePages::new(BytePageSize::Size8);
1596 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1597 pages.put_slice(&[2; 64]);
1598 let b = Bytes::from(pages);
1599 assert_eq!(&b[..64], &[1; 64][..]);
1600 assert_eq!(&b[64..], &[2; 64][..]);
1601
1602 assert!(BytesMut::from(BytePages::new(BytePageSize::Size8)).is_empty());
1603 assert!(Bytes::from(BytePages::new(BytePageSize::Size8)).is_empty());
1604 }
1605
1606 #[test]
1612 fn pages_copy_to() {
1613 let mut pages = BytePages::default();
1614 let mut pages2 = BytePages::default();
1615 pages.put_slice(b"456");
1616 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1617 pages.copy_to(&mut pages2);
1618 let p = pages.freeze();
1619 assert_eq!(p, b"123456");
1620 let p2 = pages2.freeze();
1621 assert_eq!(p2, b"123456");
1622
1623 let mut pages = BytePages::default();
1624 let mut pages2 = BytePages::default();
1625 pages.put_slice(b"456");
1626 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1627 pages.copy_to(&mut pages2);
1628 pages.put_u8(b'7');
1629 let p = pages.freeze();
1630 assert_eq!(p, b"1234567");
1631 let p2 = pages2.freeze();
1632 assert_eq!(p2, b"123456");
1633
1634 let mut pages = BytePages::default();
1635 pages.put_slice(b"456");
1636 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1637 let mut pages2 = pages.clone();
1638 pages.put_u8(b'7');
1639 let p = pages.freeze();
1640 assert_eq!(p, b"1234567");
1641 let p2 = pages2.freeze();
1642 assert_eq!(p2, b"123456");
1643 }
1644
1645 #[test]
1651 fn pages_methods() {
1652 let mut pages = BytePages::default();
1654 pages.put_slice(b"456");
1655 pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
1656 let mut pages2 = pages.split_to(1);
1657 let p = pages.freeze();
1658 assert_eq!(p, b"23456");
1659 let p2 = pages2.freeze();
1660 assert_eq!(p2, b"1");
1661
1662 let mut pages = BytePages::default();
1663 pages.put_slice(b"456");
1664 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1665 let mut pages2 = pages.split_to(4);
1666 let p = pages.freeze();
1667 assert_eq!(p, b"56");
1668 let p2 = pages2.freeze();
1669 assert_eq!(p2, b"1234");
1670
1671 let mut pages = BytePages::default();
1673 pages.put_slice(b"456");
1674 pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
1675 let mut pages2 = BytePages::default();
1676 pages.split_into(1, &mut pages2);
1677 let p = pages.freeze();
1678 assert_eq!(p, b"23456");
1679 let p2 = pages2.freeze();
1680 assert_eq!(p2, b"1");
1681
1682 let mut pages = BytePages::default();
1684 #[allow(deprecated)]
1685 pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
1686 assert_eq!(pages.len(), 3);
1687 let p = pages.freeze();
1688 assert_eq!(p, b"123");
1689
1690 let data = b"0123456789abcdef".repeat(4096);
1691
1692 let mut pages = BytePages::default();
1693 #[allow(deprecated)]
1694 pages.with_bytes_mut(|buf| buf.extend_from_slice(&data));
1695 assert_eq!(pages.len(), 65_536);
1696 let p = pages.freeze();
1697 assert_eq!(p, data[..]);
1698
1699 let page = BytePage::from(Bytes::copy_from_slice(b"123"));
1701 assert_eq!(page, b"123");
1702 assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
1703 let b = Bytes::from(page);
1704 assert_eq!(b, b"123");
1705 }
1706
1707 #[test]
1714 fn put_slice_current_page() {
1715 let mut pages = BytePages::new(BytePageSize::Size4);
1716 pages.put_slice(b"abc");
1717 let spare = pages.spare();
1718 assert!(spare > 1);
1719 assert_eq!(pages.pages().len(), 0);
1720 assert_eq!(pages.num_pages(), 1);
1721
1722 let fill = vec![b'x'; spare - 1];
1723 pages.put_slice(&fill);
1724 assert_eq!(pages.spare(), 1);
1725 assert_eq!(pages.pages().len(), 0);
1726
1727 pages.put_slice(b"y");
1728 assert_eq!(pages.pages().len(), 1);
1729 assert!(pages.current.is_none());
1730 assert_eq!(pages.num_pages(), 1);
1731 let page_len = pages.len();
1732 assert_eq!(page_len, spare + 3);
1733
1734 let large = vec![b'z'; page_len + 10];
1735 pages.put_slice(&large);
1736 assert_eq!(pages.len(), page_len * 2 + 10);
1737 assert_eq!(pages.num_pages(), 3);
1738
1739 let mut expected = b"abc".to_vec();
1740 expected.extend_from_slice(&fill);
1741 expected.push(b'y');
1742 expected.extend_from_slice(&large);
1743 assert_eq!(pages.freeze(), expected[..]);
1744 }
1745
1746 #[test]
1752 fn page_clone() {
1753 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1755 let p2 = p.clone();
1756 assert_eq!(p, p2);
1757
1758 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1760 if let StorageType::Storage(ref mut st) = p.inner {
1761 assert!(st.is_unique());
1762 } else {
1763 panic!()
1764 }
1765 let p2 = p.clone();
1766 assert_eq!(p, p2);
1767 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1769 if let StorageType::Storage(st) = p.inner {
1770 assert!(st.is_unique());
1771 } else {
1772 panic!()
1773 }
1774
1775 let mut p = BytePage::from(BytesMut::copy_from_slice([b'1'; 64]));
1776 let p2 = p.clone();
1777 assert_eq!(p, p2);
1778 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1779 if let StorageType::Storage(ref mut st) = p.inner {
1780 assert!(!st.is_unique());
1781 } else {
1782 panic!()
1783 }
1784 drop(p2);
1785 if let StorageType::Storage(st) = p.inner {
1786 assert!(st.is_unique());
1787 } else {
1788 panic!()
1789 }
1790
1791 let p = BytePage::from(vec![b'1', b'2', b'3']);
1793 let p2 = p.clone();
1794 assert_eq!(p, p2);
1795 if let StorageType::Bytes(_) = p2.inner {
1796 } else {
1797 panic!()
1798 }
1799 }
1800
1801 #[test]
1806 fn page_split_to() {
1807 let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1809 let p2 = p.split_to(1);
1810 assert_eq!(p, b"23");
1811 assert_eq!(p2, b"1");
1812
1813 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1815 let p2 = p.split_to(1);
1816 assert_eq!(p, b"23");
1817 assert_eq!(p2, b"1");
1818
1819 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1821 let p2 = p.split_to(1);
1822 assert_eq!(p, b"23");
1823 assert_eq!(p2, b"1");
1824 }
1825
1826 #[test]
1831 fn page_read() {
1832 use std::io::Read;
1833
1834 let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1835
1836 let mut buf = [0; 10];
1837 assert_eq!(page.read(&mut buf).unwrap(), 3);
1838 assert_eq!(page.len(), 0);
1839 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1840 }
1841
1842 #[test]
1848 fn pages_misc() {
1849 let mut pages = BytePages::new(BytePageSize::Size4);
1850 pages.set_page_size(BytePageSize::Size8);
1851 assert_eq!(pages.page_size(), BytePageSize::Size8);
1852 assert!(!pages.prepend(Bytes::new()));
1853 assert!(pages.prepend(Bytes::from_static(b"a")));
1854
1855 io::Write::write_all(&mut pages, b"bc").unwrap();
1856 io::Write::flush(&mut pages).unwrap();
1857 assert_eq!(pages.freeze(), "abc");
1858
1859 let s = ByteString::from_static("str");
1860 pages.append(&s);
1861 assert_eq!(pages.freeze(), "str");
1862 }
1863
1864 #[test]
1870 fn pages_try_get_current_from() {
1871 let mut src = BytePages::new(BytePageSize::Size4);
1872 src.extend_from_slice(b"data");
1873
1874 let mut dst = BytePages::new(BytePageSize::Size4);
1876 dst.append(Bytes::from_static(b"x"));
1877 dst.try_get_current_from(&mut src);
1878 assert_eq!(src.len(), 4);
1879 assert_eq!(dst.len(), 1);
1880
1881 let mut dst = BytePages::new(BytePageSize::Size4);
1882 dst.try_get_current_from(&mut src);
1883 assert_eq!(src.len(), 0);
1884 assert_eq!(dst.len(), 4);
1885 dst.extend_from_slice(b"!");
1886 assert_eq!(dst.freeze(), "data!");
1887 }
1888
1889 #[test]
1895 fn pages_drop_cache() {
1896 CACHE.with(|c| c.set(Some(Box::default())));
1897 let cached = || {
1898 CACHE.with(|c| {
1899 let cache = c.take().unwrap();
1900 let len = cache.len();
1901 c.set(Some(cache));
1902 len
1903 })
1904 };
1905
1906 let pages: Vec<_> = (0..=CACHE_SIZE)
1908 .map(|_| BytePages::new(BytePageSize::Size4))
1909 .collect();
1910 drop(pages);
1911 assert_eq!(cached(), CACHE_SIZE);
1912
1913 CACHE.with(|c| c.set(Some(Box::default())));
1915 let pages = BytePages::new(BytePageSize::Size4);
1916 let cache = CACHE.with(Cell::take);
1917 drop(pages);
1918 CACHE.with(|c| c.set(cache));
1919 assert_eq!(cached(), 0);
1920 }
1921
1922 #[test]
1928 fn page_conversions() {
1929 let page = BytePage::from(BytesMut::copy_from_slice([1; 64]));
1930 assert_eq!(page.info(), crate::info::PageKind::Storage);
1931 assert_eq!(Bytes::from(page), &[1; 64][..]);
1932
1933 let page = BytePage::from(vec![2; 64]);
1934 assert_eq!(page.info(), crate::info::PageKind::Vec);
1935 assert_eq!(Bytes::from(page), &[2; 64][..]);
1936
1937 let page = BytePage::from(vec![3; 64]);
1938 assert_eq!(BytesMut::from(page), &[3; 64][..]);
1939
1940 let s = ByteString::from_static("string");
1941 assert_eq!(BytePage::from(&s), "string");
1942 }
1943
1944 #[test]
1950 fn append_storage_page() {
1951 let mut pages = BytePages::new(BytePageSize::Size4);
1953 let mut buf = BytesMut::with_capacity(64);
1954 buf.extend_from_slice(b"a");
1955 pages.append(buf);
1956 pages.extend_from_slice(b"b");
1957 assert_eq!(pages.num_pages(), 1);
1958 assert_eq!(pages.freeze(), "ab");
1959
1960 let mut buf = BytesMut::with_capacity(64);
1962 let cap = buf.capacity();
1963 buf.resize(cap, b'x');
1964 pages.append(buf);
1965 let page = BytePage::from(BytesMut::copy_from_slice([b'y'; 64]));
1966 let shared = page.clone();
1967 pages.append(page);
1968 pages.extend_from_slice(b"z");
1969 assert_eq!(pages.num_pages(), 3);
1970 assert_eq!(pages.len(), cap + 65);
1971 assert_eq!(shared, &[b'y'; 64][..]);
1972 }
1973
1974 fn mixed_pages() -> BytePages {
1976 let mut pages = BytePages::new(BytePageSize::Size4);
1977 pages.extend_from_slice(b"current");
1978 pages.prepend(Bytes::copy_from_slice(&[b'b'; 64]));
1979 pages.prepend(Bytes::copy_from_slice(b"ab"));
1980 assert!(pages.pages()[0].is_inline());
1981 pages
1982 }
1983
1984 #[test]
1990 fn iter_pages() {
1991 let pages = BytePages::default();
1992 assert_eq!(pages.iter().count(), 0);
1993
1994 let pages = mixed_pages();
1995 let chunks: Vec<&[u8]> = pages.iter().collect();
1996 assert_eq!(chunks, [&b"ab"[..], &[b'b'; 64][..], &b"current"[..]]);
1997 assert_eq!(chunks.len(), pages.num_pages());
1998
1999 let ptrs: Vec<*const u8> = pages.iter().map(<[u8]>::as_ptr).collect();
2001 let moved = Box::new(pages);
2002 let moved_ptrs: Vec<*const u8> = moved.iter().map(<[u8]>::as_ptr).collect();
2003 assert_eq!(ptrs, moved_ptrs);
2004
2005 let mut pages = BytePages::new(BytePageSize::Size4);
2007 pages.extend_from_slice(b"data");
2008 pages.prepend(Bytes::copy_from_slice(b"ab"));
2009 pages.advance_to(6);
2010 assert_eq!(pages.iter().count(), 0);
2011 assert_eq!(pages.num_pages(), 0);
2012 }
2013
2014 #[test]
2020 fn advance_to_pages() {
2021 let mut pages = mixed_pages();
2022 let len = pages.len();
2023 pages.advance_to(0);
2024 assert_eq!(pages.len(), len);
2025
2026 pages.advance_to(2);
2028 assert_eq!(pages.len(), len - 2);
2029 assert_eq!(pages.num_pages(), 2);
2030 assert_eq!(pages.iter().next().unwrap(), &[b'b'; 64][..]);
2031
2032 pages.advance_to(60);
2034 assert_eq!(pages.len(), 11);
2035 assert_eq!(pages.num_pages(), 2);
2036 let chunks: Vec<&[u8]> = pages.iter().collect();
2037 assert_eq!(chunks, [&b"bbbb"[..], &b"current"[..]]);
2038
2039 pages.advance_to(6);
2041 assert_eq!(pages.len(), 5);
2042 assert_eq!(pages.num_pages(), 1);
2043 assert_eq!(pages.iter().next().unwrap(), b"rrent");
2044
2045 let ptr = pages.iter().next().unwrap().as_ptr();
2047 pages.advance_to(5);
2048 assert!(pages.is_empty());
2049 assert_eq!(pages.num_pages(), 0);
2050 pages.extend_from_slice(b"next");
2051 assert_eq!(pages.num_pages(), 1);
2052 assert_eq!(pages.iter().next().unwrap().as_ptr(), ptr.wrapping_add(5));
2053 assert_eq!(pages.freeze(), "next");
2054 }
2055
2056 #[test]
2062 fn move_to_keeps_pages() {
2063 let mut src = mixed_pages();
2065 let ptrs: Vec<*const u8> = src
2066 .iter()
2067 .filter(|s| s.len() > 2)
2068 .map(<[u8]>::as_ptr)
2069 .collect();
2070 let mut dst = BytePages::new(BytePageSize::Size16);
2071 src.move_to(&mut dst);
2072 assert!(src.is_empty());
2073 assert_eq!(src.num_pages(), 0);
2074 assert_eq!(dst.page_size(), BytePageSize::Size16);
2075 assert_eq!(dst.num_pages(), 3);
2076 assert_eq!(dst.len(), 73);
2077 let moved: Vec<*const u8> = dst
2078 .iter()
2079 .filter(|s| s.len() > 2)
2080 .map(<[u8]>::as_ptr)
2081 .collect();
2082 assert_eq!(ptrs, moved);
2083
2084 let mut dst = BytePages::new(BytePageSize::Size4);
2087 dst.extend_from_slice(b"first");
2088 dst.prepend(Bytes::copy_from_slice(b"0"));
2089 let mut src = mixed_pages();
2090 src.move_to(&mut dst);
2091 let chunks: Vec<&[u8]> = dst.iter().collect();
2092 assert_eq!(
2093 chunks,
2094 [
2095 &b"0"[..],
2096 &b"first"[..],
2097 &b"ab"[..],
2098 &[b'b'; 64][..],
2099 &b"current"[..]
2100 ]
2101 );
2102 assert_eq!(dst.len(), 79);
2103 dst.extend_from_slice(b"last");
2104 assert_eq!(dst.num_pages(), 6);
2105
2106 let mut src = BytePages::default();
2108 src.move_to(&mut dst);
2109 assert_eq!(dst.num_pages(), 6);
2110 }
2111
2112 #[test]
2117 fn advance_to_vec_page() {
2118 let mut pages = BytePages::default();
2119 pages.prepend(b"hello world".to_vec());
2120 pages.advance_to(6);
2121 assert_eq!(pages.len(), 5);
2122 assert_eq!(pages.freeze(), "world");
2123 }
2124
2125 #[test]
2130 #[should_panic(expected = "cannot advance past the end of the buffer")]
2131 fn advance_to_past_end() {
2132 let mut pages = mixed_pages();
2133 pages.advance_to(pages.len() + 1);
2134 }
2135}