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 fn put_slice(&mut self, mut src: &[u8]) {
565 while !src.is_empty() {
566 let amount = self.with_current(|st| st.put_slice_partial(src));
567
568 src = &src[amount..];
569 }
570 }
571
572 #[inline]
573 fn put_u8(&mut self, n: u8) {
574 self.with_current(|st| st.put_u8(n));
575 }
576
577 #[inline]
578 fn put_i8(&mut self, n: i8) {
579 self.put_u8(n as u8);
580 }
581}
582
583impl Clone for BytePages {
584 fn clone(&self) -> Self {
585 let size = self.page_size();
586 let mut pages = BytePages::new(size);
587 self.copy_to(&mut pages);
588 pages
589 }
590}
591
592impl io::Write for BytePages {
593 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
594 self.put_slice(src);
595 Ok(src.len())
596 }
597
598 fn flush(&mut self) -> Result<(), io::Error> {
599 Ok(())
600 }
601}
602
603impl From<BytePages> for Bytes {
604 fn from(mut pages: BytePages) -> Bytes {
606 pages.freeze()
607 }
608}
609
610impl From<BytePages> for BytesMut {
611 fn from(mut pages: BytePages) -> BytesMut {
614 if pages.num_pages() == 1 {
615 return BytesMut::from(pages.take().unwrap());
616 }
617
618 let mut buf = BytesMut::with_capacity(pages.len());
619 while let Some(p) = pages.take() {
620 buf.extend_from_slice(&p);
621 }
622 buf
623 }
624}
625
626pub struct BytePage {
628 inner: StorageType,
629}
630
631enum StorageType {
632 Bytes(Bytes),
633 Storage(StorageVec),
634 Vec(Vec<u8>),
635}
636
637impl BytePage {
638 #[inline]
639 pub fn len(&self) -> usize {
641 self.as_ref().len()
642 }
643
644 #[inline]
645 pub fn is_empty(&self) -> bool {
647 self.len() == 0
648 }
649
650 #[inline]
651 pub unsafe fn as_ptr(&self) -> *const u8 {
660 unsafe {
661 match &self.inner {
662 StorageType::Bytes(b) => b.storage.as_ptr(),
663 StorageType::Storage(b) => b.as_ptr(),
664 StorageType::Vec(b) => b.as_ptr(),
665 }
666 }
667 }
668
669 #[inline]
670 #[doc(hidden)]
671 pub fn info(&self) -> crate::info::PageKind {
673 match &self.inner {
674 StorageType::Bytes(_) => crate::info::PageKind::Bytes,
675 StorageType::Storage(_) => crate::info::PageKind::Storage,
676 StorageType::Vec(_) => crate::info::PageKind::Vec,
677 }
678 }
679
680 #[inline]
681 #[doc(hidden)]
682 pub fn is_inline(&self) -> bool {
687 matches!(&self.inner, StorageType::Bytes(b) if b.is_inline())
688 }
689
690 #[must_use]
702 pub fn split_to(&mut self, at: usize) -> BytePage {
703 match &mut self.inner {
704 StorageType::Bytes(b) => {
705 let buf = b.split_to(cmp::min(at, b.len()));
706 BytePage {
707 inner: StorageType::Bytes(buf),
708 }
709 }
710 StorageType::Storage(_) => {
711 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
712 if let StorageType::Storage(st) = inner {
713 self.inner = StorageType::Bytes(Bytes {
714 storage: st.freeze(),
715 });
716 self.split_to(at)
717 } else {
718 unreachable!()
719 }
720 }
721 StorageType::Vec(_) => {
722 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
723 if let StorageType::Vec(b) = inner {
724 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
725 self.split_to(at)
726 } else {
727 unreachable!()
728 }
729 }
730 }
731 }
732
733 #[inline]
743 pub fn advance_to(&mut self, cnt: usize) {
744 match &mut self.inner {
745 StorageType::Bytes(b) => b.advance_to(cnt),
746 StorageType::Storage(b) => unsafe { b.set_start(cnt) },
747 StorageType::Vec(b) => {
748 assert!(
749 cnt <= b.len(),
750 "cannot advance past the end of the buffer, cnt:{cnt} len:{}",
751 b.len()
752 );
753 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
754 }
755 }
756 }
757
758 #[inline]
760 #[must_use]
761 pub fn freeze(self) -> Bytes {
762 match self.inner {
763 StorageType::Bytes(b) => b,
764 StorageType::Storage(st) => Bytes {
765 storage: st.freeze(),
766 },
767 StorageType::Vec(v) => Bytes::from(v),
768 }
769 }
770
771 fn into_storage(self) -> Result<StorageVec, Self> {
772 if let StorageType::Storage(st) = self.inner {
773 if !st.is_full() && st.is_unique() {
775 Ok(st)
776 } else {
777 Err(Self {
778 inner: StorageType::Storage(st),
779 })
780 }
781 } else {
782 Err(self)
783 }
784 }
785}
786
787impl Clone for BytePage {
788 fn clone(&self) -> Self {
789 let inner = match &self.inner {
790 StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
791 StorageType::Storage(st) => StorageType::Bytes(Bytes {
794 storage: st.shallow_freeze(),
795 }),
796 StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
797 };
798
799 Self { inner }
800 }
801}
802
803impl AsRef<[u8]> for BytePage {
804 #[inline]
805 fn as_ref(&self) -> &[u8] {
806 match &self.inner {
807 StorageType::Bytes(b) => b.as_ref(),
808 StorageType::Storage(b) => b.as_ref(),
809 StorageType::Vec(b) => b.as_ref(),
810 }
811 }
812}
813
814impl Borrow<[u8]> for BytePage {
815 #[inline]
816 fn borrow(&self) -> &[u8] {
817 self.as_ref()
818 }
819}
820
821impl From<Bytes> for BytePage {
822 fn from(buf: Bytes) -> Self {
823 BytePage {
824 inner: StorageType::Bytes(buf),
825 }
826 }
827}
828
829impl<'a> From<&'a Bytes> for BytePage {
830 fn from(buf: &'a Bytes) -> Self {
831 BytePage {
832 inner: StorageType::Bytes(buf.clone()),
833 }
834 }
835}
836
837impl From<BytesMut> for BytePage {
838 fn from(buf: BytesMut) -> Self {
839 BytePage {
840 inner: StorageType::Storage(buf.storage),
841 }
842 }
843}
844
845impl From<ByteString> for BytePage {
846 fn from(s: ByteString) -> Self {
847 s.into_bytes().into()
848 }
849}
850
851impl<'a> From<&'a ByteString> for BytePage {
852 fn from(s: &'a ByteString) -> Self {
853 s.clone().into_bytes().into()
854 }
855}
856
857impl From<StorageVec> for BytePage {
858 fn from(buf: StorageVec) -> Self {
859 BytePage {
860 inner: StorageType::Storage(buf),
861 }
862 }
863}
864
865impl From<Vec<u8>> for BytePage {
866 fn from(buf: Vec<u8>) -> Self {
867 BytePage {
868 inner: StorageType::Vec(buf),
869 }
870 }
871}
872
873impl From<&'static str> for BytePage {
874 fn from(buf: &'static str) -> Self {
875 Bytes::from_static(buf.as_bytes()).into()
876 }
877}
878
879impl From<&'static [u8]> for BytePage {
880 fn from(buf: &'static [u8]) -> Self {
881 Bytes::from_static(buf).into()
882 }
883}
884
885impl<const N: usize> From<&'static [u8; N]> for BytePage {
886 fn from(buf: &'static [u8; N]) -> Self {
887 Bytes::from_static(buf).into()
888 }
889}
890
891impl From<BytePage> for Bytes {
892 fn from(page: BytePage) -> Self {
893 match page.inner {
894 StorageType::Bytes(b) => b,
895 StorageType::Storage(storage) => BytesMut { storage }.freeze(),
896 StorageType::Vec(v) => Bytes::copy_from_slice(&v),
897 }
898 }
899}
900
901impl From<BytePage> for BytesMut {
902 fn from(page: BytePage) -> Self {
903 match page.inner {
904 StorageType::Bytes(b) => b.into(),
905 StorageType::Storage(storage) => {
907 if storage.is_unique() {
908 BytesMut { storage }
909 } else {
910 BytesMut::copy_from_slice(storage.as_ref())
911 }
912 }
913 StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
914 }
915 }
916}
917
918impl PartialEq for BytePage {
919 fn eq(&self, other: &BytePage) -> bool {
920 self.as_ref() == other.as_ref()
921 }
922}
923
924impl_partial_eq!(BytePage);
925
926impl_read!(BytePage);
927
928impl ops::Deref for BytePage {
929 type Target = [u8];
930
931 #[inline]
932 fn deref(&self) -> &[u8] {
933 self.as_ref()
934 }
935}
936
937impl fmt::Debug for BytePage {
938 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
939 fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
940 }
941}
942
943#[cfg(test)]
944mod tests {
945 use rand::Rng;
946
947 use super::*;
948
949 #[test]
955 #[allow(clippy::op_ref, clippy::cmp_owned)]
956 fn page_eq_and_read() {
957 use std::io::Read;
958
959 let mut page = BytePage::from(Vec::from(&b"hello"[..]));
960 assert_eq!(page, b"hello"[..]);
961 assert_eq!(page, *b"hello");
962 assert_eq!(page, b"hello");
963 assert_eq!(page, &b"hello"[..]);
964 assert_eq!(page, "hello");
965 assert_eq!(page, *"hello");
966 assert_eq!(page, b"hello".to_vec());
967 assert_eq!(page, String::from("hello"));
968 assert_eq!(b"hello"[..], page);
969 assert_eq!(*b"hello", page);
970 assert_eq!(b"hello", page);
971 assert_eq!(&b"hello"[..], page);
972 assert_eq!("hello", page);
973 assert_eq!(*"hello", page);
974 assert_eq!(b"hello".to_vec(), page);
975 assert_eq!(String::from("hello"), page);
976 assert_ne!(page, "hell");
977
978 let mut buf = [0u8; 3];
979 assert_eq!(page.read(&mut buf).unwrap(), 3);
980 assert_eq!(&buf, b"hel");
981 assert_eq!(page, "lo");
982 assert_eq!(page.read(&mut buf).unwrap(), 2);
983 assert_eq!(page.read(&mut buf).unwrap(), 0);
984 assert!(page.is_empty());
985 }
986
987 #[test]
993 fn page_info() {
994 use crate::info::PageKind;
995
996 let p = BytePage::from(Bytes::copy_from_slice(&[1; 64]));
997 assert_eq!(p.info(), PageKind::Bytes);
998 let p = BytePage::from(BytesMut::copy_from_slice(&[1; 64][..]));
999 assert_eq!(p.info(), PageKind::Storage);
1000 let p = BytePage::from(vec![1; 64]);
1001 assert_eq!(p.info(), PageKind::Vec);
1002 assert!(!p.is_inline());
1003
1004 assert!(BytePage::from(Bytes::copy_from_slice(&[1; 4])).is_inline());
1005 assert!(!BytePage::from(Bytes::copy_from_slice(&[1; 64])).is_inline());
1006 assert!(!BytePage::from(BytesMut::copy_from_slice(&[1; 4][..])).is_inline());
1007 }
1008
1009 #[test]
1015 fn append_copies_small_and_splits_for_large() {
1016 let cap = BytePageSize::Size16.capacity();
1017 let mut pages = BytePages::new(BytePageSize::Size16);
1018 pages.extend_from_slice(b"head\r\n");
1019
1020 pages.append(Bytes::copy_from_slice(&[1; APPEND_COPY_LIMIT]));
1022 assert_eq!(pages.num_pages(), 1);
1023 assert_eq!(pages.current_len(), 6 + APPEND_COPY_LIMIT);
1024
1025 let body = Bytes::copy_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1027 let body_ptr = body.as_ptr();
1028 pages.append(body.clone());
1029 assert_eq!(pages.num_pages(), 2);
1030 assert_eq!(pages.current_len(), 0);
1031 assert_eq!(pages.spare(), cap - 6 - APPEND_COPY_LIMIT);
1032
1033 let page_ptr = pages.pages()[0].as_ref().as_ptr();
1035 pages.extend_from_slice(b"\r\n");
1036 assert_eq!(pages.num_pages(), 3);
1037 let tail_ptr = pages.current.as_ref().unwrap().as_ref().as_ptr();
1038 assert_eq!(tail_ptr, page_ptr.wrapping_add(6 + APPEND_COPY_LIMIT));
1039
1040 let mut expected = b"head\r\n".to_vec();
1041 expected.extend_from_slice(&[1; APPEND_COPY_LIMIT]);
1042 expected.extend_from_slice(&body);
1043 expected.extend_from_slice(b"\r\n");
1044 assert_eq!(pages.len(), expected.len());
1045
1046 let first = pages.take().unwrap();
1047 let second = pages.take().unwrap();
1048 assert_eq!(second.as_ref().as_ptr(), body_ptr);
1049 let third = pages.take().unwrap();
1050 assert!(pages.take().is_none());
1051 let data = [first.as_ref(), second.as_ref(), third.as_ref()].concat();
1052 assert_eq!(data, expected);
1053
1054 pages.extend_from_slice(b"x");
1056 pages.append(body);
1057 assert_eq!(pages.take().unwrap().as_ref(), b"x");
1058 assert_eq!(pages.take().unwrap().len(), APPEND_COPY_LIMIT + 1);
1059 assert!(pages.take().is_none());
1060 assert_eq!(pages.num_pages(), 0);
1061 assert_eq!(pages.spare(), cap - 1);
1062 }
1063
1064 #[test]
1070 fn pages() {
1071 let cap = BytePageSize::Size8.capacity();
1072 unsafe {
1073 let mut pages = BytePages::new(BytePageSize::Size8);
1075 assert!(pages.is_empty());
1076 assert_eq!(pages.len(), 0);
1077 assert_eq!(pages.num_pages(), 0);
1078 pages.extend_from_slice(b"b");
1079 assert_eq!(pages.len(), 1);
1080 assert_eq!(pages.num_pages(), 1);
1081 pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
1082 assert_eq!(pages.len(), 9217);
1083 assert_eq!(pages.num_pages(), 2);
1084 assert!(!pages.is_empty());
1085
1086 let mut pgs = BytePages::new(BytePageSize::Size8);
1087 pgs.put_i8(b'a' as i8);
1088 let p = pgs.take().unwrap();
1089 assert_eq!(p.len(), 1);
1090 assert_eq!(p.as_ref(), b"a");
1091
1092 pgs.extend_from_slice("a".repeat(cap - 1).as_bytes());
1093 assert_eq!(pgs.num_pages(), 1);
1094 pgs.put_u8(b'a');
1095 assert_eq!(pgs.num_pages(), 1);
1096 assert!(pgs.current.is_none());
1097
1098 pgs.put_u8(b'a');
1099 assert_eq!(pgs.num_pages(), 2);
1100
1101 pgs.append(Bytes::copy_from_slice("a".repeat(cap).as_bytes()));
1102 assert_eq!(pgs.num_pages(), 3);
1103 assert_eq!(pgs.current_len(), 0);
1104 assert_eq!(pgs.spare(), cap - 1);
1105
1106 let p = pages.take().unwrap();
1108 assert_eq!(p.len(), cap);
1109 let p = pages.take().unwrap();
1110 assert_eq!(p.len(), 9217 - cap);
1111 assert!(!p.is_empty());
1112 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1113 assert_eq!(p.as_ref(), "a".repeat(9217 - cap).as_bytes());
1114 assert!(pages.take().is_none());
1115
1116 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1117 assert_eq!(p.len(), 3);
1118 assert!(!p.is_empty());
1119 assert_eq!(p.as_ref(), b"123");
1120 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1121
1122 let p = BytePage::from(&b"123"[..]);
1123 assert_eq!(p.len(), 3);
1124 assert!(!p.is_empty());
1125 assert_eq!(p.as_ref(), b"123");
1126 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1127
1128 let p = BytePage::from(b"123");
1129 assert_eq!(p.len(), 3);
1130 assert!(!p.is_empty());
1131 assert_eq!(p.as_ref(), b"123");
1132 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1133
1134 let p = BytePage::from("123");
1135 assert_eq!(p.len(), 3);
1136 assert!(!p.is_empty());
1137 assert_eq!(p.as_ref(), b"123");
1138 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1139 assert_eq!(p.freeze(), b"123");
1140
1141 let p = BytePage::from(vec![b'1', b'2', b'3']);
1142 assert_eq!(p.len(), 3);
1143 assert!(!p.is_empty());
1144 assert_eq!(p.as_ref(), b"123");
1145 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1146 assert_eq!(p.freeze(), b"123");
1147
1148 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1149 p.advance_to(1);
1150 assert_eq!(p.len(), 2);
1151 assert!(!p.is_empty());
1152 assert_eq!(p.as_ref(), b"23");
1153
1154 let mut pages = BytePages::new(BytePageSize::Size8);
1156 pages.extend_from_slice(b"b");
1157 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
1158 let p = pages.take().unwrap();
1159 assert_eq!(p.as_ref(), b"b");
1160
1161 let mut pages = BytePages::new(BytePageSize::Size8);
1162 pages.extend_from_slice(b"a");
1163 pages.append(Bytes::copy_from_slice(b"123"));
1164 pages.push_back(p);
1165 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
1166
1167 assert_eq!(pages.len(), 5);
1168 pages.clear();
1169 assert_eq!(pages.len(), 0);
1170 }
1171 }
1172
1173 fn assert_len(pages: &BytePages) {
1175 let len = pages.pages().iter().map(BytePage::len).sum::<usize>() + pages.current_len();
1176 assert_eq!(pages.len(), len);
1177 assert_eq!(pages.is_empty(), len == 0);
1178 }
1179
1180 #[test]
1186 fn pages_len_tracking() {
1187 let mut rng = rand::rng();
1188 let mut pages = BytePages::new(BytePageSize::Size8);
1189 let mut other = BytePages::new(BytePageSize::Size8);
1190 let mut expected = 0;
1191
1192 let (iters, max) = if cfg!(miri) { (100, 256) } else { (2000, 12 * 1024) };
1193 for _ in 0..iters {
1194 let n = rng.random_range(0..max);
1195 match rng.random_range(0..9) {
1196 0 => {
1197 pages.extend_from_slice(&vec![1; n]);
1198 expected += n;
1199 }
1200 1 => {
1201 pages.append(Bytes::copy_from_slice(&vec![2; n]));
1202 expected += n;
1203 }
1204 2 => {
1205 if pages.prepend(BytesMut::copy_from_slice(vec![3; n])) {
1206 expected += n;
1207 }
1208 }
1209 3 => {
1210 if let Some(p) = pages.take() {
1211 expected -= p.len();
1212 }
1213 }
1214 4 => {
1215 let at = cmp::min(n, expected);
1216 let split = pages.split_to(at);
1217 assert_len(&split);
1218 assert_eq!(split.len(), at);
1219 expected -= at;
1220 }
1221 5 => {
1222 let at = cmp::min(n, expected);
1223 pages.split_into(at, &mut other);
1224 expected -= at;
1225 }
1226 6 => {
1227 other.move_to(&mut pages);
1228 assert_len(&other);
1229 assert!(other.is_empty());
1230 expected = pages.len();
1231 }
1232 7 => {
1233 let mut copy = BytePages::new(BytePageSize::Size8);
1234 pages.copy_to(&mut copy);
1235 assert_len(©);
1236 assert_eq!(copy.len(), expected);
1237 }
1238 _ => {
1239 pages.put_u8(4);
1240 expected += 1;
1241 }
1242 }
1243 assert_len(&pages);
1244 assert_len(&other);
1245 assert_eq!(pages.len(), expected);
1246 }
1247
1248 let len = pages.len();
1249 assert_eq!(pages.freeze().len(), len);
1250 assert_len(&pages);
1251 assert!(pages.is_empty());
1252 pages.extend_from_slice(b"123");
1253 pages.clear();
1254 assert_len(&pages);
1255 assert!(pages.is_empty());
1256 }
1257
1258 #[test]
1263 fn pages_len_after_cache_reuse() {
1264 let mut pages = BytePages::new(BytePageSize::Size8);
1265 pages.append(Bytes::copy_from_slice(&[1; 64]));
1266 pages.append(Bytes::copy_from_slice(&[1; 64]));
1267 drop(pages);
1268
1269 let pages = BytePages::new(BytePageSize::Size8);
1270 assert_len(&pages);
1271 assert!(pages.is_empty());
1272 }
1273
1274 #[test]
1280 fn pages_copy_to_shares_current() {
1281 let mut pages = BytePages::new(BytePageSize::Size8);
1282 pages.put_slice(&[1; 64]);
1283 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1284
1285 let mut copy = BytePages::new(BytePageSize::Size8);
1286 pages.copy_to(&mut copy);
1287 let page = copy.take().unwrap();
1288 assert_eq!(unsafe { page.as_ptr() }, ptr.cast_const());
1289 assert_eq!(page.as_ref(), &[1; 64][..]);
1290
1291 pages.put_slice(&[2; 64]);
1293 assert_eq!(unsafe { pages.current.as_ref().unwrap().as_ptr() }, ptr);
1294 assert_eq!(page.as_ref(), &[1; 64][..]);
1295 assert_eq!(pages.len(), 128);
1296
1297 drop(pages);
1298 assert_eq!(page.as_ref(), &[1; 64][..]);
1299 }
1300
1301 #[test]
1307 fn pages_split_keeps_current_writable() {
1308 let mut pages = BytePages::new(BytePageSize::Size8);
1309 pages.put_slice(&[1; 64]);
1310 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1311 let remaining = pages.spare();
1312
1313 let mut head = pages.split_to(40);
1314 assert_eq!(head.len(), 40);
1315 assert_eq!(pages.len(), 24);
1316 assert_eq!(pages.num_pages(), 1);
1317 assert_eq!(pages.spare(), remaining);
1318
1319 pages.put_slice(&[2; 16]);
1321 assert_eq!(pages.num_pages(), 1);
1322 assert_eq!(
1323 unsafe { pages.current.as_ref().unwrap().as_ptr() },
1324 ptr.wrapping_add(40)
1325 );
1326 let mut expected = vec![1; 24];
1327 expected.extend_from_slice(&[2; 16]);
1328 assert_eq!(&pages.freeze()[..], &expected[..]);
1329 assert_eq!(&head.freeze()[..], &[1; 40][..]);
1330
1331 let mut pages = BytePages::new(BytePageSize::Size8);
1333 pages.put_slice(&[1; 64]);
1334 let mut to = BytePages::new(BytePageSize::Size8);
1335 pages.split_into(2, &mut to);
1336 assert_eq!(&to.freeze()[..], &[1; 2][..]);
1337 assert_eq!(pages.spare(), remaining);
1338 assert_eq!(pages.len(), 62);
1339
1340 let mut pages = BytePages::new(BytePageSize::Size8);
1342 pages.put_slice(&[1; 64]);
1343 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1344 let to = pages.split_to(64);
1345 assert!(pages.is_empty());
1346 assert_eq!(pages.num_pages(), 0);
1347 assert_eq!(to.spare(), remaining);
1348 assert_eq!(unsafe { to.current.as_ref().unwrap().as_ptr() }, ptr);
1349
1350 let mut pages = BytePages::new(BytePageSize::Size8);
1352 let _ = pages.chunk_mut();
1353 let head = pages.split_to(10);
1354 assert!(head.is_empty());
1355 assert_eq!(pages.spare(), remaining + 64);
1356 }
1357
1358 #[test]
1364 fn pages_buf_mut_grows() {
1365 let mut pages = BytePages::new(BytePageSize::Size8);
1366 assert!(pages.has_remaining_mut());
1367 assert_eq!(pages.remaining_mut(), usize::MAX);
1368 unsafe { pages.advance_mut(0) };
1369
1370 let n = pages.chunk_mut().len();
1372 unsafe {
1373 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1374 pages.advance_mut(n);
1375 }
1376 assert!(pages.chunk_mut().len() > 0);
1377 assert_eq!(pages.num_pages(), 1);
1379 unsafe {
1380 *pages.chunk_mut().as_mut_ptr() = 2;
1381 pages.advance_mut(1);
1382 }
1383 assert_eq!(pages.len(), n + 1);
1384 assert_eq!(pages.remaining_mut(), usize::MAX - n - 1);
1385
1386 let mut pages = BytePages::new(BytePageSize::Size8);
1388 pages.put(&[3u8; 200][..]);
1389 pages.put(Bytes::from_static(b"abcd"));
1390 io::Write::write_all(&mut pages, &[4; 100]).unwrap();
1391 let mut expected = vec![3; 200];
1392 expected.extend_from_slice(b"abcd");
1393 expected.extend_from_slice(&[4; 100]);
1394 assert_eq!(&pages.freeze()[..], &expected[..]);
1395 }
1396
1397 #[test]
1403 fn pages_byte_write_after_full_page() {
1404 let mut pages = BytePages::new(BytePageSize::Size8);
1406 let n = pages.chunk_mut().len();
1407 unsafe {
1408 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1409 pages.advance_mut(n);
1410 }
1411 pages.put_u8(2);
1412 pages.put_i8(3);
1413 assert_eq!(pages.num_pages(), 2);
1414 assert_eq!(pages.pages()[0].len(), n);
1415 let mut expected = vec![1; n];
1416 expected.extend_from_slice(&[2, 3]);
1417 assert_eq!(&pages.freeze()[..], &expected[..]);
1418
1419 let mut pages = BytePages::new(BytePageSize::Size8);
1421 let n = pages.chunk_mut().len();
1422 unsafe {
1423 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1424 pages.advance_mut(n);
1425 }
1426 pages.append(vec![2; APPEND_COPY_LIMIT + 1]);
1427 pages.put_u8(3);
1428 assert!(pages.pages().iter().all(|p| !p.is_empty()));
1429 let mut expected = vec![1; n];
1430 expected.extend_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1431 expected.push(3);
1432 assert_eq!(&pages.freeze()[..], &expected[..]);
1433 }
1434
1435 #[test]
1440 #[should_panic(expected = "cannot advance past the current page")]
1441 fn pages_advance_past_current_page() {
1442 let mut pages = BytePages::new(BytePageSize::Size8);
1443 let n = pages.chunk_mut().len();
1444 unsafe { pages.advance_mut(n + 1) };
1445 }
1446
1447 #[test]
1452 #[should_panic(expected = "Page size cannot be Unset")]
1453 fn pages_new_unset() {
1454 let _ = BytePages::new(BytePageSize::Unset);
1455 }
1456
1457 #[test]
1462 #[should_panic(expected = "Page size cannot be Unset")]
1463 fn pages_set_page_size_unset() {
1464 let mut pages = BytePages::new(BytePageSize::Size8);
1465 pages.set_page_size(BytePageSize::Unset);
1466 }
1467
1468 #[test]
1473 fn cached_pages_list_is_shrunk() {
1474 let mut pages = BytePages::new(BytePageSize::Size4);
1475 for _ in 0..200 {
1476 pages.append(Bytes::from_static(b"page"));
1477 }
1478 assert!(pages.pages().capacity() >= 200);
1479 drop(pages);
1480
1481 let pages = BytePages::new(BytePageSize::Size4);
1482 assert!(
1483 pages.pages().capacity() < 200,
1484 "{}",
1485 pages.pages().capacity()
1486 );
1487 }
1488
1489 #[test]
1495 fn pages_into_bytes_single_page() {
1496 let mut pages = BytePages::new(BytePageSize::Size8);
1498 pages.put_slice(&[1; 64]);
1499 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1500 let mut buf = BytesMut::from(pages);
1501 assert_eq!(buf.as_ptr(), ptr.cast_const());
1502 assert_eq!(&buf[..], &[1; 64][..]);
1503 assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
1505 buf.extend_from_slice(&[2; 64]);
1506 assert_eq!(buf.as_ptr(), ptr.cast_const());
1507
1508 let mut pages = BytePages::new(BytePageSize::Size8);
1509 pages.put_slice(&[1; 64]);
1510 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1511 let b = Bytes::from(pages);
1512 assert_eq!(b.as_ptr(), ptr.cast_const());
1513 assert_eq!(&b[..], &[1; 64][..]);
1514
1515 let src = Bytes::copy_from_slice(&[3; 64]);
1517 let ptr = src.as_ptr();
1518 let mut pages = BytePages::new(BytePageSize::Size8);
1519 pages.prepend(src);
1520 assert_eq!(BytesMut::from(pages).as_ptr(), ptr);
1521
1522 let src = Bytes::copy_from_slice(&[3; 64]);
1524 let mut pages = BytePages::new(BytePageSize::Size8);
1525 pages.prepend(&src);
1526 let mut buf = BytesMut::from(pages);
1527 assert_ne!(buf.as_ptr(), src.as_ptr());
1528 buf[0] = 4;
1529 assert_eq!(&src[..], &[3; 64][..]);
1530 }
1531
1532 #[test]
1538 fn pages_into_bytes_multiple_pages() {
1539 let mut pages = BytePages::new(BytePageSize::Size8);
1540 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1541 pages.put_slice(&[2; 64]);
1542 assert_eq!(pages.num_pages(), 2);
1543 let buf = BytesMut::from(pages);
1544 assert_eq!(&buf[..64], &[1; 64][..]);
1545 assert_eq!(&buf[64..], &[2; 64][..]);
1546
1547 let mut pages = BytePages::new(BytePageSize::Size8);
1548 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1549 pages.put_slice(&[2; 64]);
1550 let b = Bytes::from(pages);
1551 assert_eq!(&b[..64], &[1; 64][..]);
1552 assert_eq!(&b[64..], &[2; 64][..]);
1553
1554 assert!(BytesMut::from(BytePages::new(BytePageSize::Size8)).is_empty());
1555 assert!(Bytes::from(BytePages::new(BytePageSize::Size8)).is_empty());
1556 }
1557
1558 #[test]
1564 fn pages_copy_to() {
1565 let mut pages = BytePages::default();
1566 let mut pages2 = BytePages::default();
1567 pages.put_slice(b"456");
1568 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1569 pages.copy_to(&mut pages2);
1570 let p = pages.freeze();
1571 assert_eq!(p, b"123456");
1572 let p2 = pages2.freeze();
1573 assert_eq!(p2, b"123456");
1574
1575 let mut pages = BytePages::default();
1576 let mut pages2 = BytePages::default();
1577 pages.put_slice(b"456");
1578 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1579 pages.copy_to(&mut pages2);
1580 pages.put_u8(b'7');
1581 let p = pages.freeze();
1582 assert_eq!(p, b"1234567");
1583 let p2 = pages2.freeze();
1584 assert_eq!(p2, b"123456");
1585
1586 let mut pages = BytePages::default();
1587 pages.put_slice(b"456");
1588 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1589 let mut pages2 = pages.clone();
1590 pages.put_u8(b'7');
1591 let p = pages.freeze();
1592 assert_eq!(p, b"1234567");
1593 let p2 = pages2.freeze();
1594 assert_eq!(p2, b"123456");
1595 }
1596
1597 #[test]
1603 fn pages_methods() {
1604 let mut pages = BytePages::default();
1606 pages.put_slice(b"456");
1607 pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
1608 let mut pages2 = pages.split_to(1);
1609 let p = pages.freeze();
1610 assert_eq!(p, b"23456");
1611 let p2 = pages2.freeze();
1612 assert_eq!(p2, b"1");
1613
1614 let mut pages = BytePages::default();
1615 pages.put_slice(b"456");
1616 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1617 let mut pages2 = pages.split_to(4);
1618 let p = pages.freeze();
1619 assert_eq!(p, b"56");
1620 let p2 = pages2.freeze();
1621 assert_eq!(p2, b"1234");
1622
1623 let mut pages = BytePages::default();
1625 pages.put_slice(b"456");
1626 pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
1627 let mut pages2 = BytePages::default();
1628 pages.split_into(1, &mut pages2);
1629 let p = pages.freeze();
1630 assert_eq!(p, b"23456");
1631 let p2 = pages2.freeze();
1632 assert_eq!(p2, b"1");
1633
1634 let mut pages = BytePages::default();
1636 #[allow(deprecated)]
1637 pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
1638 assert_eq!(pages.len(), 3);
1639 let p = pages.freeze();
1640 assert_eq!(p, b"123");
1641
1642 let data = b"0123456789abcdef".repeat(4096);
1643
1644 let mut pages = BytePages::default();
1645 #[allow(deprecated)]
1646 pages.with_bytes_mut(|buf| buf.extend_from_slice(&data));
1647 assert_eq!(pages.len(), 65_536);
1648 let p = pages.freeze();
1649 assert_eq!(p, data[..]);
1650
1651 let page = BytePage::from(Bytes::copy_from_slice(b"123"));
1653 assert_eq!(page, b"123");
1654 assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
1655 let b = Bytes::from(page);
1656 assert_eq!(b, b"123");
1657 }
1658
1659 #[test]
1665 fn page_clone() {
1666 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1668 let p2 = p.clone();
1669 assert_eq!(p, p2);
1670
1671 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1673 if let StorageType::Storage(ref mut st) = p.inner {
1674 assert!(st.is_unique());
1675 } else {
1676 panic!()
1677 }
1678 let p2 = p.clone();
1679 assert_eq!(p, p2);
1680 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1682 if let StorageType::Storage(st) = p.inner {
1683 assert!(st.is_unique());
1684 } else {
1685 panic!()
1686 }
1687
1688 let mut p = BytePage::from(BytesMut::copy_from_slice([b'1'; 64]));
1689 let p2 = p.clone();
1690 assert_eq!(p, p2);
1691 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1692 if let StorageType::Storage(ref mut st) = p.inner {
1693 assert!(!st.is_unique());
1694 } else {
1695 panic!()
1696 }
1697 drop(p2);
1698 if let StorageType::Storage(st) = p.inner {
1699 assert!(st.is_unique());
1700 } else {
1701 panic!()
1702 }
1703
1704 let p = BytePage::from(vec![b'1', b'2', b'3']);
1706 let p2 = p.clone();
1707 assert_eq!(p, p2);
1708 if let StorageType::Bytes(_) = p2.inner {
1709 } else {
1710 panic!()
1711 }
1712 }
1713
1714 #[test]
1719 fn page_split_to() {
1720 let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1722 let p2 = p.split_to(1);
1723 assert_eq!(p, b"23");
1724 assert_eq!(p2, b"1");
1725
1726 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1728 let p2 = p.split_to(1);
1729 assert_eq!(p, b"23");
1730 assert_eq!(p2, b"1");
1731
1732 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1734 let p2 = p.split_to(1);
1735 assert_eq!(p, b"23");
1736 assert_eq!(p2, b"1");
1737 }
1738
1739 #[test]
1744 fn page_read() {
1745 use std::io::Read;
1746
1747 let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1748
1749 let mut buf = [0; 10];
1750 assert_eq!(page.read(&mut buf).unwrap(), 3);
1751 assert_eq!(page.len(), 0);
1752 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1753 }
1754
1755 #[test]
1761 fn pages_misc() {
1762 let mut pages = BytePages::new(BytePageSize::Size4);
1763 pages.set_page_size(BytePageSize::Size8);
1764 assert_eq!(pages.page_size(), BytePageSize::Size8);
1765 assert!(!pages.prepend(Bytes::new()));
1766 assert!(pages.prepend(Bytes::from_static(b"a")));
1767
1768 io::Write::write_all(&mut pages, b"bc").unwrap();
1769 io::Write::flush(&mut pages).unwrap();
1770 assert_eq!(pages.freeze(), "abc");
1771
1772 let s = ByteString::from_static("str");
1773 pages.append(&s);
1774 assert_eq!(pages.freeze(), "str");
1775 }
1776
1777 #[test]
1783 fn pages_try_get_current_from() {
1784 let mut src = BytePages::new(BytePageSize::Size4);
1785 src.extend_from_slice(b"data");
1786
1787 let mut dst = BytePages::new(BytePageSize::Size4);
1789 dst.append(Bytes::from_static(b"x"));
1790 dst.try_get_current_from(&mut src);
1791 assert_eq!(src.len(), 4);
1792 assert_eq!(dst.len(), 1);
1793
1794 let mut dst = BytePages::new(BytePageSize::Size4);
1795 dst.try_get_current_from(&mut src);
1796 assert_eq!(src.len(), 0);
1797 assert_eq!(dst.len(), 4);
1798 dst.extend_from_slice(b"!");
1799 assert_eq!(dst.freeze(), "data!");
1800 }
1801
1802 #[test]
1808 fn pages_drop_cache() {
1809 CACHE.with(|c| c.set(Some(Box::default())));
1810 let cached = || {
1811 CACHE.with(|c| {
1812 let cache = c.take().unwrap();
1813 let len = cache.len();
1814 c.set(Some(cache));
1815 len
1816 })
1817 };
1818
1819 let pages: Vec<_> = (0..=CACHE_SIZE)
1821 .map(|_| BytePages::new(BytePageSize::Size4))
1822 .collect();
1823 drop(pages);
1824 assert_eq!(cached(), CACHE_SIZE);
1825
1826 CACHE.with(|c| c.set(Some(Box::default())));
1828 let pages = BytePages::new(BytePageSize::Size4);
1829 let cache = CACHE.with(Cell::take);
1830 drop(pages);
1831 CACHE.with(|c| c.set(cache));
1832 assert_eq!(cached(), 0);
1833 }
1834
1835 #[test]
1841 fn page_conversions() {
1842 let page = BytePage::from(BytesMut::copy_from_slice([1; 64]));
1843 assert_eq!(page.info(), crate::info::PageKind::Storage);
1844 assert_eq!(Bytes::from(page), &[1; 64][..]);
1845
1846 let page = BytePage::from(vec![2; 64]);
1847 assert_eq!(page.info(), crate::info::PageKind::Vec);
1848 assert_eq!(Bytes::from(page), &[2; 64][..]);
1849
1850 let page = BytePage::from(vec![3; 64]);
1851 assert_eq!(BytesMut::from(page), &[3; 64][..]);
1852
1853 let s = ByteString::from_static("string");
1854 assert_eq!(BytePage::from(&s), "string");
1855 }
1856
1857 #[test]
1863 fn append_storage_page() {
1864 let mut pages = BytePages::new(BytePageSize::Size4);
1866 let mut buf = BytesMut::with_capacity(64);
1867 buf.extend_from_slice(b"a");
1868 pages.append(buf);
1869 pages.extend_from_slice(b"b");
1870 assert_eq!(pages.num_pages(), 1);
1871 assert_eq!(pages.freeze(), "ab");
1872
1873 let mut buf = BytesMut::with_capacity(64);
1875 let cap = buf.capacity();
1876 buf.resize(cap, b'x');
1877 pages.append(buf);
1878 let page = BytePage::from(BytesMut::copy_from_slice([b'y'; 64]));
1879 let shared = page.clone();
1880 pages.append(page);
1881 pages.extend_from_slice(b"z");
1882 assert_eq!(pages.num_pages(), 3);
1883 assert_eq!(pages.len(), cap + 65);
1884 assert_eq!(shared, &[b'y'; 64][..]);
1885 }
1886
1887 fn mixed_pages() -> BytePages {
1889 let mut pages = BytePages::new(BytePageSize::Size4);
1890 pages.extend_from_slice(b"current");
1891 pages.prepend(Bytes::copy_from_slice(&[b'b'; 64]));
1892 pages.prepend(Bytes::copy_from_slice(b"ab"));
1893 assert!(pages.pages()[0].is_inline());
1894 pages
1895 }
1896
1897 #[test]
1903 fn iter_pages() {
1904 let pages = BytePages::default();
1905 assert_eq!(pages.iter().count(), 0);
1906
1907 let pages = mixed_pages();
1908 let chunks: Vec<&[u8]> = pages.iter().collect();
1909 assert_eq!(chunks, [&b"ab"[..], &[b'b'; 64][..], &b"current"[..]]);
1910 assert_eq!(chunks.len(), pages.num_pages());
1911
1912 let ptrs: Vec<*const u8> = pages.iter().map(<[u8]>::as_ptr).collect();
1914 let moved = Box::new(pages);
1915 let moved_ptrs: Vec<*const u8> = moved.iter().map(<[u8]>::as_ptr).collect();
1916 assert_eq!(ptrs, moved_ptrs);
1917
1918 let mut pages = BytePages::new(BytePageSize::Size4);
1920 pages.extend_from_slice(b"data");
1921 pages.prepend(Bytes::copy_from_slice(b"ab"));
1922 pages.advance_to(6);
1923 assert_eq!(pages.iter().count(), 0);
1924 assert_eq!(pages.num_pages(), 0);
1925 }
1926
1927 #[test]
1933 fn advance_to_pages() {
1934 let mut pages = mixed_pages();
1935 let len = pages.len();
1936 pages.advance_to(0);
1937 assert_eq!(pages.len(), len);
1938
1939 pages.advance_to(2);
1941 assert_eq!(pages.len(), len - 2);
1942 assert_eq!(pages.num_pages(), 2);
1943 assert_eq!(pages.iter().next().unwrap(), &[b'b'; 64][..]);
1944
1945 pages.advance_to(60);
1947 assert_eq!(pages.len(), 11);
1948 assert_eq!(pages.num_pages(), 2);
1949 let chunks: Vec<&[u8]> = pages.iter().collect();
1950 assert_eq!(chunks, [&b"bbbb"[..], &b"current"[..]]);
1951
1952 pages.advance_to(6);
1954 assert_eq!(pages.len(), 5);
1955 assert_eq!(pages.num_pages(), 1);
1956 assert_eq!(pages.iter().next().unwrap(), b"rrent");
1957
1958 let ptr = pages.iter().next().unwrap().as_ptr();
1960 pages.advance_to(5);
1961 assert!(pages.is_empty());
1962 assert_eq!(pages.num_pages(), 0);
1963 pages.extend_from_slice(b"next");
1964 assert_eq!(pages.num_pages(), 1);
1965 assert_eq!(pages.iter().next().unwrap().as_ptr(), ptr.wrapping_add(5));
1966 assert_eq!(pages.freeze(), "next");
1967 }
1968
1969 #[test]
1975 fn move_to_keeps_pages() {
1976 let mut src = mixed_pages();
1978 let ptrs: Vec<*const u8> = src
1979 .iter()
1980 .filter(|s| s.len() > 2)
1981 .map(<[u8]>::as_ptr)
1982 .collect();
1983 let mut dst = BytePages::new(BytePageSize::Size16);
1984 src.move_to(&mut dst);
1985 assert!(src.is_empty());
1986 assert_eq!(src.num_pages(), 0);
1987 assert_eq!(dst.page_size(), BytePageSize::Size16);
1988 assert_eq!(dst.num_pages(), 3);
1989 assert_eq!(dst.len(), 73);
1990 let moved: Vec<*const u8> = dst
1991 .iter()
1992 .filter(|s| s.len() > 2)
1993 .map(<[u8]>::as_ptr)
1994 .collect();
1995 assert_eq!(ptrs, moved);
1996
1997 let mut dst = BytePages::new(BytePageSize::Size4);
2000 dst.extend_from_slice(b"first");
2001 dst.prepend(Bytes::copy_from_slice(b"0"));
2002 let mut src = mixed_pages();
2003 src.move_to(&mut dst);
2004 let chunks: Vec<&[u8]> = dst.iter().collect();
2005 assert_eq!(
2006 chunks,
2007 [
2008 &b"0"[..],
2009 &b"first"[..],
2010 &b"ab"[..],
2011 &[b'b'; 64][..],
2012 &b"current"[..]
2013 ]
2014 );
2015 assert_eq!(dst.len(), 79);
2016 dst.extend_from_slice(b"last");
2017 assert_eq!(dst.num_pages(), 6);
2018
2019 let mut src = BytePages::default();
2021 src.move_to(&mut dst);
2022 assert_eq!(dst.num_pages(), 6);
2023 }
2024
2025 #[test]
2030 fn advance_to_vec_page() {
2031 let mut pages = BytePages::default();
2032 pages.prepend(b"hello world".to_vec());
2033 pages.advance_to(6);
2034 assert_eq!(pages.len(), 5);
2035 assert_eq!(pages.freeze(), "world");
2036 }
2037
2038 #[test]
2043 #[should_panic(expected = "cannot advance past the end of the buffer")]
2044 fn advance_to_past_end() {
2045 let mut pages = mixed_pages();
2046 pages.advance_to(pages.len() + 1);
2047 }
2048}