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) {
310 if self.is_empty() {
311 return;
312 }
313
314 let len = self.current_len();
315 let copy = len != 0
316 && len < APPEND_COPY_LIMIT
317 && len < pages.spare()
318 && self
319 .current
320 .as_ref()
321 .is_some_and(|st| match st.page_size() {
322 BytePageSize::Size4 => false,
323 BytePageSize::Unset => st.capacity() >= 8 * 1024,
324 _ => true,
325 });
326
327 if !self.pages().is_empty() {
328 pages.split_current();
329 let src = self.st.as_mut().unwrap();
330 let dst = pages.st.as_mut().unwrap();
331 if dst.pages.is_empty() {
332 mem::swap(&mut src.pages, &mut dst.pages);
333 dst.len = mem::take(&mut src.len);
334 } else {
335 while let Some(page) = self.pop_front() {
336 pages.push_back(page);
337 }
338 }
339 }
340
341 if copy {
342 let st = self.current.as_mut().unwrap();
343 pages.put_slice(st.as_ref());
344 st.truncate(0);
345 } else if len != 0
346 && let Some(st) = self.current.take()
347 {
348 pages.split_current();
349 pages.push_back(BytePage::from(st));
350 }
351 }
352
353 fn split_current(&mut self) {
356 if let Some(st) = self.current.as_mut()
357 && st.len() != 0
358 {
359 let head = st.split_to(st.len());
360 self.push_back(<BytePage as From<Bytes>>::from(Bytes { storage: head }));
361 }
362 }
363
364 #[must_use]
376 pub fn split_to(&mut self, at: usize) -> BytePages {
377 let mut pages = BytePages::new(self.page_size());
378 self.split_into(at, &mut pages);
379 pages
380 }
381
382 pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
393 while let Some(mut page) = self.pop_front() {
394 let len = cmp::min(page.len(), at);
395 to.append(page.split_to(len));
396
397 if !page.is_empty() {
398 self.push_front(page);
399 return;
400 }
401 at -= len;
402 }
403 if at > 0
404 && let Some(mut st) = self.current.take()
405 {
406 if at < st.len() {
407 to.append(Bytes {
409 storage: st.split_to(at),
410 });
411 self.current = Some(st);
412 } else if st.len() == 0 {
413 self.current = Some(st);
414 } else {
415 to.append(BytePage::from(st));
416 }
417 }
418 }
419
420 #[inline]
422 pub fn clear(&mut self) {
423 while self.take().is_some() {}
424 }
425
426 #[inline]
428 #[must_use]
429 pub fn freeze(&mut self) -> Bytes {
430 let pages = self.num_pages();
431 if pages == 0 || self.is_empty() {
432 Bytes::new()
433 } else if pages == 1 {
434 self.take().unwrap().freeze()
435 } else {
436 let mut buf = BytesMut::with_capacity(self.len());
437 while let Some(p) = self.take() {
438 buf.extend_from_slice(&p);
439 }
440 buf.freeze()
441 }
442 }
443
444 #[inline]
445 pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
447 if self.pages().is_empty()
448 && self.current.is_none()
449 && let Some(st) = pages.current.take()
450 {
451 self.current = Some(st);
452 }
453 }
454
455 #[doc(hidden)]
465 #[deprecated(
466 since = "1.10.0",
467 note = "use the `BufMut` methods of `BytePages` instead"
468 )]
469 pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
470 where
471 F: FnOnce(&mut BytesMut) -> R,
472 {
473 let mut buf = BytesMut::new();
474 let res = f(&mut buf);
475 self.append(buf);
476 res
477 }
478
479 fn take_writable(&mut self) -> StorageVec {
484 match self.current.take() {
485 Some(st) if !st.is_full() => st,
486 Some(st) => {
487 if st.len() != 0 {
488 self.push_back(BytePage::from(st));
489 }
490 StorageVec::sized(self.page_size())
491 }
492 None => StorageVec::sized(self.page_size()),
493 }
494 }
495
496 fn with_current<F, R>(&mut self, f: F) -> R
497 where
498 F: FnOnce(&mut StorageVec) -> R,
499 {
500 let mut st = self.take_writable();
501 let result = f(&mut st);
502
503 if st.is_full() {
505 self.push_back(BytePage::from(st));
506 } else {
507 self.current = Some(st);
508 }
509
510 result
511 }
512}
513
514impl Drop for BytePages {
515 fn drop(&mut self) {
516 if let Some(mut st) = self.st.take() {
517 st.pages.clear();
518 st.pages.shrink_to(8);
520 st.len = 0;
521 let _ = CACHE.try_with(move |c| {
523 if let Some(mut cache) = c.take() {
524 if cache.len() < CACHE_SIZE {
525 cache.push(st);
526 }
527 c.set(Some(cache));
528 }
529 });
530 }
531 }
532}
533
534impl fmt::Debug for BytePages {
535 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
536 let mut f = fmt.debug_tuple("BytePages");
537 for p in self.pages() {
538 f.field(p);
539 }
540 if let Some(st) = &self.current {
541 f.field(&crate::debug::BsDebug(st.as_ref()));
542 }
543 f.finish()
544 }
545}
546
547impl Default for BytePages {
548 fn default() -> Self {
549 BytePages::new(BytePageSize::Size8)
550 }
551}
552
553impl BufMut for BytePages {
557 #[inline]
558 fn remaining_mut(&self) -> usize {
559 usize::MAX - self.len()
560 }
561
562 #[inline]
563 unsafe fn advance_mut(&mut self, cnt: usize) {
564 if cnt == 0 {
565 return;
566 }
567 let spare = self.spare();
568 assert!(
569 cnt <= spare,
570 "cannot advance past the current page: {cnt:?} <= {spare:?}"
571 );
572 let st = self.current.as_mut().unwrap();
573 st.set_len(st.len() + cnt);
574 }
575
576 #[inline]
577 fn chunk_mut(&mut self) -> &mut UninitSlice {
578 let st = self.take_writable();
579 self.current.insert(st).spare_mut()
580 }
581
582 fn put<T: Buf>(&mut self, mut src: T)
583 where
584 Self: Sized,
585 {
586 while src.has_remaining() {
587 let chunk = src.chunk();
588 let len = chunk.len();
589 self.put_slice(chunk);
590 src.advance(len);
591 }
592 }
593
594 #[inline]
595 fn put_slice(&mut self, src: &[u8]) {
596 if let Some(st) = self.current.as_mut()
598 && st.remaining() > src.len()
599 {
600 st.put_slice_partial(src);
601 } else {
602 self.put_slice_pages(src);
603 }
604 }
605
606 #[inline]
607 fn put_u8(&mut self, n: u8) {
608 self.with_current(|st| st.put_u8(n));
609 }
610
611 #[inline]
612 fn put_i8(&mut self, n: i8) {
613 self.put_u8(n as u8);
614 }
615}
616
617impl BytePages {
618 fn put_slice_pages(&mut self, mut src: &[u8]) {
619 while !src.is_empty() {
620 let amount = self.with_current(|st| st.put_slice_partial(src));
621
622 src = &src[amount..];
623 }
624 }
625}
626
627impl Clone for BytePages {
628 fn clone(&self) -> Self {
629 let size = self.page_size();
630 let mut pages = BytePages::new(size);
631 self.copy_to(&mut pages);
632 pages
633 }
634}
635
636impl io::Write for BytePages {
637 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
638 self.put_slice(src);
639 Ok(src.len())
640 }
641
642 fn flush(&mut self) -> Result<(), io::Error> {
643 Ok(())
644 }
645}
646
647impl From<BytePages> for Bytes {
648 fn from(mut pages: BytePages) -> Bytes {
650 pages.freeze()
651 }
652}
653
654impl From<BytePages> for BytesMut {
655 fn from(mut pages: BytePages) -> BytesMut {
658 if pages.num_pages() == 1 {
659 return BytesMut::from(pages.take().unwrap());
660 }
661
662 let mut buf = BytesMut::with_capacity(pages.len());
663 while let Some(p) = pages.take() {
664 buf.extend_from_slice(&p);
665 }
666 buf
667 }
668}
669
670pub struct BytePage {
672 inner: StorageType,
673}
674
675enum StorageType {
676 Bytes(Bytes),
677 Storage(StorageVec),
678 Vec(Vec<u8>),
679}
680
681impl BytePage {
682 #[inline]
683 pub fn len(&self) -> usize {
685 self.as_ref().len()
686 }
687
688 #[inline]
689 pub fn is_empty(&self) -> bool {
691 self.len() == 0
692 }
693
694 #[inline]
695 pub unsafe fn as_ptr(&self) -> *const u8 {
704 unsafe {
707 match &self.inner {
708 StorageType::Bytes(b) => b.storage.as_ptr(),
709 StorageType::Storage(b) => b.as_ptr(),
710 StorageType::Vec(b) => b.as_ptr(),
711 }
712 }
713 }
714
715 #[inline]
716 #[doc(hidden)]
717 pub fn info(&self) -> crate::info::PageKind {
719 match &self.inner {
720 StorageType::Bytes(_) => crate::info::PageKind::Bytes,
721 StorageType::Storage(_) => crate::info::PageKind::Storage,
722 StorageType::Vec(_) => crate::info::PageKind::Vec,
723 }
724 }
725
726 #[inline]
727 #[doc(hidden)]
728 pub fn is_inline(&self) -> bool {
733 matches!(&self.inner, StorageType::Bytes(b) if b.is_inline())
734 }
735
736 #[must_use]
748 pub fn split_to(&mut self, at: usize) -> BytePage {
749 match &mut self.inner {
750 StorageType::Bytes(b) => {
751 let buf = b.split_to(cmp::min(at, b.len()));
752 BytePage {
753 inner: StorageType::Bytes(buf),
754 }
755 }
756 StorageType::Storage(_) => {
757 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
758 if let StorageType::Storage(st) = inner {
759 self.inner = StorageType::Bytes(Bytes {
760 storage: st.freeze(),
761 });
762 self.split_to(at)
763 } else {
764 unreachable!()
765 }
766 }
767 StorageType::Vec(_) => {
768 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
769 if let StorageType::Vec(b) = inner {
770 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
771 self.split_to(at)
772 } else {
773 unreachable!()
774 }
775 }
776 }
777 }
778
779 #[inline]
789 pub fn advance_to(&mut self, cnt: usize) {
790 match &mut self.inner {
791 StorageType::Bytes(b) => b.advance_to(cnt),
792 StorageType::Storage(b) => unsafe { b.set_start(cnt) },
795 StorageType::Vec(b) => {
796 assert!(
797 cnt <= b.len(),
798 "cannot advance past the end of the buffer, cnt:{cnt} len:{}",
799 b.len()
800 );
801 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
802 }
803 }
804 }
805
806 #[inline]
808 #[must_use]
809 pub fn freeze(self) -> Bytes {
810 match self.inner {
811 StorageType::Bytes(b) => b,
812 StorageType::Storage(st) => Bytes {
813 storage: st.freeze(),
814 },
815 StorageType::Vec(v) => Bytes::from(v),
816 }
817 }
818
819 fn into_storage(self) -> Result<StorageVec, Self> {
820 if let StorageType::Storage(st) = self.inner {
821 if !st.is_full() && st.is_unique() {
823 Ok(st)
824 } else {
825 Err(Self {
826 inner: StorageType::Storage(st),
827 })
828 }
829 } else {
830 Err(self)
831 }
832 }
833}
834
835impl Clone for BytePage {
836 fn clone(&self) -> Self {
837 let inner = match &self.inner {
838 StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
839 StorageType::Storage(st) => StorageType::Bytes(Bytes {
842 storage: st.shallow_freeze(),
843 }),
844 StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
845 };
846
847 Self { inner }
848 }
849}
850
851impl AsRef<[u8]> for BytePage {
852 #[inline]
853 fn as_ref(&self) -> &[u8] {
854 match &self.inner {
855 StorageType::Bytes(b) => b.as_ref(),
856 StorageType::Storage(b) => b.as_ref(),
857 StorageType::Vec(b) => b.as_ref(),
858 }
859 }
860}
861
862impl Borrow<[u8]> for BytePage {
863 #[inline]
864 fn borrow(&self) -> &[u8] {
865 self.as_ref()
866 }
867}
868
869impl From<Bytes> for BytePage {
870 fn from(buf: Bytes) -> Self {
871 BytePage {
872 inner: StorageType::Bytes(buf),
873 }
874 }
875}
876
877impl<'a> From<&'a Bytes> for BytePage {
878 fn from(buf: &'a Bytes) -> Self {
879 BytePage {
880 inner: StorageType::Bytes(buf.clone()),
881 }
882 }
883}
884
885impl From<BytesMut> for BytePage {
886 fn from(buf: BytesMut) -> Self {
887 BytePage {
888 inner: StorageType::Storage(buf.storage),
889 }
890 }
891}
892
893impl From<ByteString> for BytePage {
894 fn from(s: ByteString) -> Self {
895 s.into_bytes().into()
896 }
897}
898
899impl<'a> From<&'a ByteString> for BytePage {
900 fn from(s: &'a ByteString) -> Self {
901 s.clone().into_bytes().into()
902 }
903}
904
905impl From<StorageVec> for BytePage {
906 fn from(buf: StorageVec) -> Self {
907 BytePage {
908 inner: StorageType::Storage(buf),
909 }
910 }
911}
912
913impl From<Vec<u8>> for BytePage {
914 fn from(buf: Vec<u8>) -> Self {
915 BytePage {
916 inner: StorageType::Vec(buf),
917 }
918 }
919}
920
921impl From<&'static str> for BytePage {
922 fn from(buf: &'static str) -> Self {
923 Bytes::from_static(buf.as_bytes()).into()
924 }
925}
926
927impl From<&'static [u8]> for BytePage {
928 fn from(buf: &'static [u8]) -> Self {
929 Bytes::from_static(buf).into()
930 }
931}
932
933impl<const N: usize> From<&'static [u8; N]> for BytePage {
934 fn from(buf: &'static [u8; N]) -> Self {
935 Bytes::from_static(buf).into()
936 }
937}
938
939impl From<BytePage> for Bytes {
940 fn from(page: BytePage) -> Self {
941 match page.inner {
942 StorageType::Bytes(b) => b,
943 StorageType::Storage(storage) => BytesMut { storage }.freeze(),
944 StorageType::Vec(v) => Bytes::copy_from_slice(&v),
945 }
946 }
947}
948
949impl From<BytePage> for BytesMut {
950 fn from(page: BytePage) -> Self {
951 match page.inner {
952 StorageType::Bytes(b) => b.into(),
953 StorageType::Storage(storage) => {
955 if storage.is_unique() {
956 BytesMut { storage }
957 } else {
958 BytesMut::copy_from_slice(storage.as_ref())
959 }
960 }
961 StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
962 }
963 }
964}
965
966impl PartialEq for BytePage {
967 fn eq(&self, other: &BytePage) -> bool {
968 self.as_ref() == other.as_ref()
969 }
970}
971
972impl_partial_eq!(BytePage);
973
974impl_read!(BytePage);
975
976impl ops::Deref for BytePage {
977 type Target = [u8];
978
979 #[inline]
980 fn deref(&self) -> &[u8] {
981 self.as_ref()
982 }
983}
984
985impl fmt::Debug for BytePage {
986 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
987 fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
988 }
989}
990
991#[cfg(test)]
992mod tests {
993 use rand::Rng;
994
995 use super::*;
996
997 #[test]
1003 #[allow(clippy::op_ref, clippy::cmp_owned)]
1004 fn page_eq_and_read() {
1005 use std::io::Read;
1006
1007 let mut page = BytePage::from(Vec::from(&b"hello"[..]));
1008 assert_eq!(page, b"hello"[..]);
1009 assert_eq!(page, *b"hello");
1010 assert_eq!(page, b"hello");
1011 assert_eq!(page, &b"hello"[..]);
1012 assert_eq!(page, "hello");
1013 assert_eq!(page, *"hello");
1014 assert_eq!(page, b"hello".to_vec());
1015 assert_eq!(page, String::from("hello"));
1016 assert_eq!(b"hello"[..], page);
1017 assert_eq!(*b"hello", page);
1018 assert_eq!(b"hello", page);
1019 assert_eq!(&b"hello"[..], page);
1020 assert_eq!("hello", page);
1021 assert_eq!(*"hello", page);
1022 assert_eq!(b"hello".to_vec(), page);
1023 assert_eq!(String::from("hello"), page);
1024 assert_ne!(page, "hell");
1025
1026 let mut buf = [0u8; 3];
1027 assert_eq!(page.read(&mut buf).unwrap(), 3);
1028 assert_eq!(&buf, b"hel");
1029 assert_eq!(page, "lo");
1030 assert_eq!(page.read(&mut buf).unwrap(), 2);
1031 assert_eq!(page.read(&mut buf).unwrap(), 0);
1032 assert!(page.is_empty());
1033 }
1034
1035 #[test]
1041 fn page_info() {
1042 use crate::info::PageKind;
1043
1044 let p = BytePage::from(Bytes::copy_from_slice(&[1; 64]));
1045 assert_eq!(p.info(), PageKind::Bytes);
1046 let p = BytePage::from(BytesMut::copy_from_slice(&[1; 64][..]));
1047 assert_eq!(p.info(), PageKind::Storage);
1048 let p = BytePage::from(vec![1; 64]);
1049 assert_eq!(p.info(), PageKind::Vec);
1050 assert!(!p.is_inline());
1051
1052 assert!(BytePage::from(Bytes::copy_from_slice(&[1; 4])).is_inline());
1053 assert!(!BytePage::from(Bytes::copy_from_slice(&[1; 64])).is_inline());
1054 assert!(!BytePage::from(BytesMut::copy_from_slice(&[1; 4][..])).is_inline());
1055 }
1056
1057 #[test]
1063 fn append_copies_small_and_splits_for_large() {
1064 let cap = BytePageSize::Size16.capacity();
1065 let mut pages = BytePages::new(BytePageSize::Size16);
1066 pages.extend_from_slice(b"head\r\n");
1067
1068 pages.append(Bytes::copy_from_slice(&[1; APPEND_COPY_LIMIT]));
1070 assert_eq!(pages.num_pages(), 1);
1071 assert_eq!(pages.current_len(), 6 + APPEND_COPY_LIMIT);
1072
1073 let body = Bytes::copy_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1075 let body_ptr = body.as_ptr();
1076 pages.append(body.clone());
1077 assert_eq!(pages.num_pages(), 2);
1078 assert_eq!(pages.current_len(), 0);
1079 assert_eq!(pages.spare(), cap - 6 - APPEND_COPY_LIMIT);
1080
1081 let page_ptr = pages.pages()[0].as_ref().as_ptr();
1083 pages.extend_from_slice(b"\r\n");
1084 assert_eq!(pages.num_pages(), 3);
1085 let tail_ptr = pages.current.as_ref().unwrap().as_ref().as_ptr();
1086 assert_eq!(tail_ptr, page_ptr.wrapping_add(6 + APPEND_COPY_LIMIT));
1087
1088 let mut expected = b"head\r\n".to_vec();
1089 expected.extend_from_slice(&[1; APPEND_COPY_LIMIT]);
1090 expected.extend_from_slice(&body);
1091 expected.extend_from_slice(b"\r\n");
1092 assert_eq!(pages.len(), expected.len());
1093
1094 let first = pages.take().unwrap();
1095 let second = pages.take().unwrap();
1096 assert_eq!(second.as_ref().as_ptr(), body_ptr);
1097 let third = pages.take().unwrap();
1098 assert!(pages.take().is_none());
1099 let data = [first.as_ref(), second.as_ref(), third.as_ref()].concat();
1100 assert_eq!(data, expected);
1101
1102 pages.extend_from_slice(b"x");
1104 pages.append(body);
1105 assert_eq!(pages.take().unwrap().as_ref(), b"x");
1106 assert_eq!(pages.take().unwrap().len(), APPEND_COPY_LIMIT + 1);
1107 assert!(pages.take().is_none());
1108 assert_eq!(pages.num_pages(), 0);
1109 assert_eq!(pages.spare(), cap - 1);
1110 }
1111
1112 #[test]
1118 fn pages() {
1119 let cap = BytePageSize::Size8.capacity();
1120 unsafe {
1123 let mut pages = BytePages::new(BytePageSize::Size8);
1125 assert!(pages.is_empty());
1126 assert_eq!(pages.len(), 0);
1127 assert_eq!(pages.num_pages(), 0);
1128 pages.extend_from_slice(b"b");
1129 assert_eq!(pages.len(), 1);
1130 assert_eq!(pages.num_pages(), 1);
1131 pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
1132 assert_eq!(pages.len(), 9217);
1133 assert_eq!(pages.num_pages(), 2);
1134 assert!(!pages.is_empty());
1135
1136 let mut pgs = BytePages::new(BytePageSize::Size8);
1137 pgs.put_i8(b'a' as i8);
1138 let p = pgs.take().unwrap();
1139 assert_eq!(p.len(), 1);
1140 assert_eq!(p.as_ref(), b"a");
1141
1142 pgs.extend_from_slice("a".repeat(cap - 1).as_bytes());
1143 assert_eq!(pgs.num_pages(), 1);
1144 pgs.put_u8(b'a');
1145 assert_eq!(pgs.num_pages(), 1);
1146 assert!(pgs.current.is_none());
1147
1148 pgs.put_u8(b'a');
1149 assert_eq!(pgs.num_pages(), 2);
1150
1151 pgs.append(Bytes::copy_from_slice("a".repeat(cap).as_bytes()));
1152 assert_eq!(pgs.num_pages(), 3);
1153 assert_eq!(pgs.current_len(), 0);
1154 assert_eq!(pgs.spare(), cap - 1);
1155
1156 let p = pages.take().unwrap();
1158 assert_eq!(p.len(), cap);
1159 let p = pages.take().unwrap();
1160 assert_eq!(p.len(), 9217 - cap);
1161 assert!(!p.is_empty());
1162 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1163 assert_eq!(p.as_ref(), "a".repeat(9217 - cap).as_bytes());
1164 assert!(pages.take().is_none());
1165
1166 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1167 assert_eq!(p.len(), 3);
1168 assert!(!p.is_empty());
1169 assert_eq!(p.as_ref(), b"123");
1170 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1171
1172 let p = BytePage::from(&b"123"[..]);
1173 assert_eq!(p.len(), 3);
1174 assert!(!p.is_empty());
1175 assert_eq!(p.as_ref(), b"123");
1176 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1177
1178 let p = BytePage::from(b"123");
1179 assert_eq!(p.len(), 3);
1180 assert!(!p.is_empty());
1181 assert_eq!(p.as_ref(), b"123");
1182 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1183
1184 let p = BytePage::from("123");
1185 assert_eq!(p.len(), 3);
1186 assert!(!p.is_empty());
1187 assert_eq!(p.as_ref(), b"123");
1188 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1189 assert_eq!(p.freeze(), b"123");
1190
1191 let p = BytePage::from(vec![b'1', b'2', b'3']);
1192 assert_eq!(p.len(), 3);
1193 assert!(!p.is_empty());
1194 assert_eq!(p.as_ref(), b"123");
1195 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1196 assert_eq!(p.freeze(), b"123");
1197
1198 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1199 p.advance_to(1);
1200 assert_eq!(p.len(), 2);
1201 assert!(!p.is_empty());
1202 assert_eq!(p.as_ref(), b"23");
1203
1204 let mut pages = BytePages::new(BytePageSize::Size8);
1206 pages.extend_from_slice(b"b");
1207 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
1208 let p = pages.take().unwrap();
1209 assert_eq!(p.as_ref(), b"b");
1210
1211 let mut pages = BytePages::new(BytePageSize::Size8);
1212 pages.extend_from_slice(b"a");
1213 pages.append(Bytes::copy_from_slice(b"123"));
1214 pages.push_back(p);
1215 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
1216
1217 assert_eq!(pages.len(), 5);
1218 pages.clear();
1219 assert_eq!(pages.len(), 0);
1220 }
1221 }
1222
1223 fn assert_len(pages: &BytePages) {
1225 let len = pages.pages().iter().map(BytePage::len).sum::<usize>() + pages.current_len();
1226 assert_eq!(pages.len(), len);
1227 assert_eq!(pages.is_empty(), len == 0);
1228 }
1229
1230 #[test]
1236 fn pages_len_tracking() {
1237 let mut rng = rand::rng();
1238 let mut pages = BytePages::new(BytePageSize::Size8);
1239 let mut other = BytePages::new(BytePageSize::Size8);
1240 let mut expected = 0;
1241
1242 let (iters, max) = if cfg!(miri) { (100, 256) } else { (2000, 12 * 1024) };
1243 for _ in 0..iters {
1244 let n = rng.random_range(0..max);
1245 match rng.random_range(0..9) {
1246 0 => {
1247 pages.extend_from_slice(&vec![1; n]);
1248 expected += n;
1249 }
1250 1 => {
1251 pages.append(Bytes::copy_from_slice(&vec![2; n]));
1252 expected += n;
1253 }
1254 2 => {
1255 if pages.prepend(BytesMut::copy_from_slice(vec![3; n])) {
1256 expected += n;
1257 }
1258 }
1259 3 => {
1260 if let Some(p) = pages.take() {
1261 expected -= p.len();
1262 }
1263 }
1264 4 => {
1265 let at = cmp::min(n, expected);
1266 let split = pages.split_to(at);
1267 assert_len(&split);
1268 assert_eq!(split.len(), at);
1269 expected -= at;
1270 }
1271 5 => {
1272 let at = cmp::min(n, expected);
1273 pages.split_into(at, &mut other);
1274 expected -= at;
1275 }
1276 6 => {
1277 other.move_to(&mut pages);
1278 assert_len(&other);
1279 assert!(other.is_empty());
1280 expected = pages.len();
1281 }
1282 7 => {
1283 let mut copy = BytePages::new(BytePageSize::Size8);
1284 pages.copy_to(&mut copy);
1285 assert_len(©);
1286 assert_eq!(copy.len(), expected);
1287 }
1288 _ => {
1289 pages.put_u8(4);
1290 expected += 1;
1291 }
1292 }
1293 assert_len(&pages);
1294 assert_len(&other);
1295 assert_eq!(pages.len(), expected);
1296 }
1297
1298 let len = pages.len();
1299 assert_eq!(pages.freeze().len(), len);
1300 assert_len(&pages);
1301 assert!(pages.is_empty());
1302 pages.extend_from_slice(b"123");
1303 pages.clear();
1304 assert_len(&pages);
1305 assert!(pages.is_empty());
1306 }
1307
1308 #[test]
1313 fn pages_len_after_cache_reuse() {
1314 let mut pages = BytePages::new(BytePageSize::Size8);
1315 pages.append(Bytes::copy_from_slice(&[1; 64]));
1316 pages.append(Bytes::copy_from_slice(&[1; 64]));
1317 drop(pages);
1318
1319 let pages = BytePages::new(BytePageSize::Size8);
1320 assert_len(&pages);
1321 assert!(pages.is_empty());
1322 }
1323
1324 #[test]
1330 fn pages_copy_to_shares_current() {
1331 let mut pages = BytePages::new(BytePageSize::Size8);
1332 pages.put_slice(&[1; 64]);
1333 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1336
1337 let mut copy = BytePages::new(BytePageSize::Size8);
1338 pages.copy_to(&mut copy);
1339 let page = copy.take().unwrap();
1340 assert_eq!(unsafe { page.as_ptr() }, ptr.cast_const());
1342 assert_eq!(page.as_ref(), &[1; 64][..]);
1343
1344 pages.put_slice(&[2; 64]);
1346 assert_eq!(unsafe { pages.current.as_ref().unwrap().as_ptr() }, ptr);
1349 assert_eq!(page.as_ref(), &[1; 64][..]);
1350 assert_eq!(pages.len(), 128);
1351
1352 drop(pages);
1353 assert_eq!(page.as_ref(), &[1; 64][..]);
1354 }
1355
1356 #[test]
1362 fn pages_split_keeps_current_writable() {
1363 let mut pages = BytePages::new(BytePageSize::Size8);
1364 pages.put_slice(&[1; 64]);
1365 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1368 let remaining = pages.spare();
1369
1370 let mut head = pages.split_to(40);
1371 assert_eq!(head.len(), 40);
1372 assert_eq!(pages.len(), 24);
1373 assert_eq!(pages.num_pages(), 1);
1374 assert_eq!(pages.spare(), remaining);
1375
1376 pages.put_slice(&[2; 16]);
1378 assert_eq!(pages.num_pages(), 1);
1379 assert_eq!(
1380 unsafe { pages.current.as_ref().unwrap().as_ptr() },
1383 ptr.wrapping_add(40)
1384 );
1385 let mut expected = vec![1; 24];
1386 expected.extend_from_slice(&[2; 16]);
1387 assert_eq!(&pages.freeze()[..], &expected[..]);
1388 assert_eq!(&head.freeze()[..], &[1; 40][..]);
1389
1390 let mut pages = BytePages::new(BytePageSize::Size8);
1392 pages.put_slice(&[1; 64]);
1393 let mut to = BytePages::new(BytePageSize::Size8);
1394 pages.split_into(2, &mut to);
1395 assert_eq!(&to.freeze()[..], &[1; 2][..]);
1396 assert_eq!(pages.spare(), remaining);
1397 assert_eq!(pages.len(), 62);
1398
1399 let mut pages = BytePages::new(BytePageSize::Size8);
1401 pages.put_slice(&[1; 64]);
1402 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1405 let to = pages.split_to(64);
1406 assert!(pages.is_empty());
1407 assert_eq!(pages.num_pages(), 0);
1408 assert_eq!(to.spare(), remaining);
1409 assert_eq!(unsafe { to.current.as_ref().unwrap().as_ptr() }, ptr);
1412
1413 let mut pages = BytePages::new(BytePageSize::Size8);
1415 let _ = pages.chunk_mut();
1416 let head = pages.split_to(10);
1417 assert!(head.is_empty());
1418 assert_eq!(pages.spare(), remaining + 64);
1419 }
1420
1421 #[test]
1427 fn pages_buf_mut_grows() {
1428 let mut pages = BytePages::new(BytePageSize::Size8);
1429 assert!(pages.has_remaining_mut());
1430 assert_eq!(pages.remaining_mut(), usize::MAX);
1431 unsafe { pages.advance_mut(0) };
1433
1434 let n = pages.chunk_mut().len();
1436 unsafe {
1439 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1440 pages.advance_mut(n);
1441 }
1442 assert!(pages.chunk_mut().len() > 0);
1443 assert_eq!(pages.num_pages(), 1);
1445 unsafe {
1448 *pages.chunk_mut().as_mut_ptr() = 2;
1449 pages.advance_mut(1);
1450 }
1451 assert_eq!(pages.len(), n + 1);
1452 assert_eq!(pages.remaining_mut(), usize::MAX - n - 1);
1453
1454 let mut pages = BytePages::new(BytePageSize::Size8);
1456 pages.put(&[3u8; 200][..]);
1457 pages.put(Bytes::from_static(b"abcd"));
1458 io::Write::write_all(&mut pages, &[4; 100]).unwrap();
1459 let mut expected = vec![3; 200];
1460 expected.extend_from_slice(b"abcd");
1461 expected.extend_from_slice(&[4; 100]);
1462 assert_eq!(&pages.freeze()[..], &expected[..]);
1463 }
1464
1465 #[test]
1471 fn pages_byte_write_after_full_page() {
1472 let mut pages = BytePages::new(BytePageSize::Size8);
1474 let n = pages.chunk_mut().len();
1475 unsafe {
1478 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1479 pages.advance_mut(n);
1480 }
1481 pages.put_u8(2);
1482 pages.put_i8(3);
1483 assert_eq!(pages.num_pages(), 2);
1484 assert_eq!(pages.pages()[0].len(), n);
1485 let mut expected = vec![1; n];
1486 expected.extend_from_slice(&[2, 3]);
1487 assert_eq!(&pages.freeze()[..], &expected[..]);
1488
1489 let mut pages = BytePages::new(BytePageSize::Size8);
1491 let n = pages.chunk_mut().len();
1492 unsafe {
1495 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1496 pages.advance_mut(n);
1497 }
1498 pages.append(vec![2; APPEND_COPY_LIMIT + 1]);
1499 pages.put_u8(3);
1500 assert!(pages.pages().iter().all(|p| !p.is_empty()));
1501 let mut expected = vec![1; n];
1502 expected.extend_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1503 expected.push(3);
1504 assert_eq!(&pages.freeze()[..], &expected[..]);
1505 }
1506
1507 #[test]
1512 #[should_panic(expected = "cannot advance past the current page")]
1513 fn pages_advance_past_current_page() {
1514 let mut pages = BytePages::new(BytePageSize::Size8);
1515 let n = pages.chunk_mut().len();
1516 unsafe { pages.advance_mut(n + 1) };
1519 }
1520
1521 #[test]
1526 #[should_panic(expected = "Page size cannot be Unset")]
1527 fn pages_new_unset() {
1528 let _ = BytePages::new(BytePageSize::Unset);
1529 }
1530
1531 #[test]
1536 #[should_panic(expected = "Page size cannot be Unset")]
1537 fn pages_set_page_size_unset() {
1538 let mut pages = BytePages::new(BytePageSize::Size8);
1539 pages.set_page_size(BytePageSize::Unset);
1540 }
1541
1542 #[test]
1547 fn cached_pages_list_is_shrunk() {
1548 let mut pages = BytePages::new(BytePageSize::Size4);
1549 for _ in 0..200 {
1550 pages.append(Bytes::from_static(b"page"));
1551 }
1552 assert!(pages.pages().capacity() >= 200);
1553 drop(pages);
1554
1555 let pages = BytePages::new(BytePageSize::Size4);
1556 assert!(
1557 pages.pages().capacity() < 200,
1558 "{}",
1559 pages.pages().capacity()
1560 );
1561 }
1562
1563 #[test]
1569 fn pages_into_bytes_single_page() {
1570 let mut pages = BytePages::new(BytePageSize::Size8);
1572 pages.put_slice(&[1; 64]);
1573 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1576 let mut buf = BytesMut::from(pages);
1577 assert_eq!(buf.as_ptr(), ptr.cast_const());
1578 assert_eq!(&buf[..], &[1; 64][..]);
1579 assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
1581 buf.extend_from_slice(&[2; 64]);
1582 assert_eq!(buf.as_ptr(), ptr.cast_const());
1583
1584 let mut pages = BytePages::new(BytePageSize::Size8);
1585 pages.put_slice(&[1; 64]);
1586 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1589 let b = Bytes::from(pages);
1590 assert_eq!(b.as_ptr(), ptr.cast_const());
1591 assert_eq!(&b[..], &[1; 64][..]);
1592
1593 let src = Bytes::copy_from_slice(&[3; 64]);
1595 let ptr = src.as_ptr();
1596 let mut pages = BytePages::new(BytePageSize::Size8);
1597 pages.prepend(src);
1598 assert_eq!(BytesMut::from(pages).as_ptr(), ptr);
1599
1600 let src = Bytes::copy_from_slice(&[3; 64]);
1602 let mut pages = BytePages::new(BytePageSize::Size8);
1603 pages.prepend(&src);
1604 let mut buf = BytesMut::from(pages);
1605 assert_ne!(buf.as_ptr(), src.as_ptr());
1606 buf[0] = 4;
1607 assert_eq!(&src[..], &[3; 64][..]);
1608 }
1609
1610 #[test]
1616 fn pages_into_bytes_multiple_pages() {
1617 let mut pages = BytePages::new(BytePageSize::Size8);
1618 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1619 pages.put_slice(&[2; 64]);
1620 assert_eq!(pages.num_pages(), 2);
1621 let buf = BytesMut::from(pages);
1622 assert_eq!(&buf[..64], &[1; 64][..]);
1623 assert_eq!(&buf[64..], &[2; 64][..]);
1624
1625 let mut pages = BytePages::new(BytePageSize::Size8);
1626 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1627 pages.put_slice(&[2; 64]);
1628 let b = Bytes::from(pages);
1629 assert_eq!(&b[..64], &[1; 64][..]);
1630 assert_eq!(&b[64..], &[2; 64][..]);
1631
1632 assert!(BytesMut::from(BytePages::new(BytePageSize::Size8)).is_empty());
1633 assert!(Bytes::from(BytePages::new(BytePageSize::Size8)).is_empty());
1634 }
1635
1636 #[test]
1642 fn pages_copy_to() {
1643 let mut pages = BytePages::default();
1644 let mut pages2 = BytePages::default();
1645 pages.put_slice(b"456");
1646 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1647 pages.copy_to(&mut pages2);
1648 let p = pages.freeze();
1649 assert_eq!(p, b"123456");
1650 let p2 = pages2.freeze();
1651 assert_eq!(p2, b"123456");
1652
1653 let mut pages = BytePages::default();
1654 let mut pages2 = BytePages::default();
1655 pages.put_slice(b"456");
1656 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1657 pages.copy_to(&mut pages2);
1658 pages.put_u8(b'7');
1659 let p = pages.freeze();
1660 assert_eq!(p, b"1234567");
1661 let p2 = pages2.freeze();
1662 assert_eq!(p2, b"123456");
1663
1664 let mut pages = BytePages::default();
1665 pages.put_slice(b"456");
1666 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1667 let mut pages2 = pages.clone();
1668 pages.put_u8(b'7');
1669 let p = pages.freeze();
1670 assert_eq!(p, b"1234567");
1671 let p2 = pages2.freeze();
1672 assert_eq!(p2, b"123456");
1673 }
1674
1675 #[test]
1681 fn pages_methods() {
1682 let mut pages = BytePages::default();
1684 pages.put_slice(b"456");
1685 pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
1686 let mut pages2 = pages.split_to(1);
1687 let p = pages.freeze();
1688 assert_eq!(p, b"23456");
1689 let p2 = pages2.freeze();
1690 assert_eq!(p2, b"1");
1691
1692 let mut pages = BytePages::default();
1693 pages.put_slice(b"456");
1694 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1695 let mut pages2 = pages.split_to(4);
1696 let p = pages.freeze();
1697 assert_eq!(p, b"56");
1698 let p2 = pages2.freeze();
1699 assert_eq!(p2, b"1234");
1700
1701 let mut pages = BytePages::default();
1703 pages.put_slice(b"456");
1704 pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
1705 let mut pages2 = BytePages::default();
1706 pages.split_into(1, &mut pages2);
1707 let p = pages.freeze();
1708 assert_eq!(p, b"23456");
1709 let p2 = pages2.freeze();
1710 assert_eq!(p2, b"1");
1711
1712 let mut pages = BytePages::default();
1714 #[allow(deprecated)]
1715 pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
1716 assert_eq!(pages.len(), 3);
1717 let p = pages.freeze();
1718 assert_eq!(p, b"123");
1719
1720 let data = b"0123456789abcdef".repeat(4096);
1721
1722 let mut pages = BytePages::default();
1723 #[allow(deprecated)]
1724 pages.with_bytes_mut(|buf| buf.extend_from_slice(&data));
1725 assert_eq!(pages.len(), 65_536);
1726 let p = pages.freeze();
1727 assert_eq!(p, data[..]);
1728
1729 let page = BytePage::from(Bytes::copy_from_slice(b"123"));
1731 assert_eq!(page, b"123");
1732 assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
1733 let b = Bytes::from(page);
1734 assert_eq!(b, b"123");
1735 }
1736
1737 #[test]
1744 fn put_slice_current_page() {
1745 let mut pages = BytePages::new(BytePageSize::Size4);
1746 pages.put_slice(b"abc");
1747 let spare = pages.spare();
1748 assert!(spare > 1);
1749 assert_eq!(pages.pages().len(), 0);
1750 assert_eq!(pages.num_pages(), 1);
1751
1752 let fill = vec![b'x'; spare - 1];
1753 pages.put_slice(&fill);
1754 assert_eq!(pages.spare(), 1);
1755 assert_eq!(pages.pages().len(), 0);
1756
1757 pages.put_slice(b"y");
1758 assert_eq!(pages.pages().len(), 1);
1759 assert!(pages.current.is_none());
1760 assert_eq!(pages.num_pages(), 1);
1761 let page_len = pages.len();
1762 assert_eq!(page_len, spare + 3);
1763
1764 let large = vec![b'z'; page_len + 10];
1765 pages.put_slice(&large);
1766 assert_eq!(pages.len(), page_len * 2 + 10);
1767 assert_eq!(pages.num_pages(), 3);
1768
1769 let mut expected = b"abc".to_vec();
1770 expected.extend_from_slice(&fill);
1771 expected.push(b'y');
1772 expected.extend_from_slice(&large);
1773 assert_eq!(pages.freeze(), expected[..]);
1774 }
1775
1776 #[test]
1782 fn page_clone() {
1783 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1785 let p2 = p.clone();
1786 assert_eq!(p, p2);
1787
1788 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1790 if let StorageType::Storage(ref mut st) = p.inner {
1791 assert!(st.is_unique());
1792 } else {
1793 panic!()
1794 }
1795 let p2 = p.clone();
1796 assert_eq!(p, p2);
1797 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1799 if let StorageType::Storage(st) = p.inner {
1800 assert!(st.is_unique());
1801 } else {
1802 panic!()
1803 }
1804
1805 let mut p = BytePage::from(BytesMut::copy_from_slice([b'1'; 64]));
1806 let p2 = p.clone();
1807 assert_eq!(p, p2);
1808 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1809 if let StorageType::Storage(ref mut st) = p.inner {
1810 assert!(!st.is_unique());
1811 } else {
1812 panic!()
1813 }
1814 drop(p2);
1815 if let StorageType::Storage(st) = p.inner {
1816 assert!(st.is_unique());
1817 } else {
1818 panic!()
1819 }
1820
1821 let p = BytePage::from(vec![b'1', b'2', b'3']);
1823 let p2 = p.clone();
1824 assert_eq!(p, p2);
1825 if let StorageType::Bytes(_) = p2.inner {
1826 } else {
1827 panic!()
1828 }
1829 }
1830
1831 #[test]
1836 fn page_split_to() {
1837 let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1839 let p2 = p.split_to(1);
1840 assert_eq!(p, b"23");
1841 assert_eq!(p2, b"1");
1842
1843 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1845 let p2 = p.split_to(1);
1846 assert_eq!(p, b"23");
1847 assert_eq!(p2, b"1");
1848
1849 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1851 let p2 = p.split_to(1);
1852 assert_eq!(p, b"23");
1853 assert_eq!(p2, b"1");
1854 }
1855
1856 #[test]
1861 fn page_read() {
1862 use std::io::Read;
1863
1864 let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1865
1866 let mut buf = [0; 10];
1867 assert_eq!(page.read(&mut buf).unwrap(), 3);
1868 assert_eq!(page.len(), 0);
1869 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1870 }
1871
1872 #[test]
1878 fn pages_misc() {
1879 let mut pages = BytePages::new(BytePageSize::Size4);
1880 pages.set_page_size(BytePageSize::Size8);
1881 assert_eq!(pages.page_size(), BytePageSize::Size8);
1882 assert!(!pages.prepend(Bytes::new()));
1883 assert!(pages.prepend(Bytes::from_static(b"a")));
1884
1885 io::Write::write_all(&mut pages, b"bc").unwrap();
1886 io::Write::flush(&mut pages).unwrap();
1887 assert_eq!(pages.freeze(), "abc");
1888
1889 let s = ByteString::from_static("str");
1890 pages.append(&s);
1891 assert_eq!(pages.freeze(), "str");
1892 }
1893
1894 #[test]
1900 fn pages_try_get_current_from() {
1901 let mut src = BytePages::new(BytePageSize::Size4);
1902 src.extend_from_slice(b"data");
1903
1904 let mut dst = BytePages::new(BytePageSize::Size4);
1906 dst.append(Bytes::from_static(b"x"));
1907 dst.try_get_current_from(&mut src);
1908 assert_eq!(src.len(), 4);
1909 assert_eq!(dst.len(), 1);
1910
1911 let mut dst = BytePages::new(BytePageSize::Size4);
1912 dst.try_get_current_from(&mut src);
1913 assert_eq!(src.len(), 0);
1914 assert_eq!(dst.len(), 4);
1915 dst.extend_from_slice(b"!");
1916 assert_eq!(dst.freeze(), "data!");
1917 }
1918
1919 #[test]
1925 fn pages_drop_cache() {
1926 CACHE.with(|c| c.set(Some(Box::default())));
1927 let cached = || {
1928 CACHE.with(|c| {
1929 let cache = c.take().unwrap();
1930 let len = cache.len();
1931 c.set(Some(cache));
1932 len
1933 })
1934 };
1935
1936 let pages: Vec<_> = (0..=CACHE_SIZE)
1938 .map(|_| BytePages::new(BytePageSize::Size4))
1939 .collect();
1940 drop(pages);
1941 assert_eq!(cached(), CACHE_SIZE);
1942
1943 CACHE.with(|c| c.set(Some(Box::default())));
1945 let pages = BytePages::new(BytePageSize::Size4);
1946 let cache = CACHE.with(Cell::take);
1947 drop(pages);
1948 CACHE.with(|c| c.set(cache));
1949 assert_eq!(cached(), 0);
1950 }
1951
1952 #[test]
1958 fn page_conversions() {
1959 let page = BytePage::from(BytesMut::copy_from_slice([1; 64]));
1960 assert_eq!(page.info(), crate::info::PageKind::Storage);
1961 assert_eq!(Bytes::from(page), &[1; 64][..]);
1962
1963 let page = BytePage::from(vec![2; 64]);
1964 assert_eq!(page.info(), crate::info::PageKind::Vec);
1965 assert_eq!(Bytes::from(page), &[2; 64][..]);
1966
1967 let page = BytePage::from(vec![3; 64]);
1968 assert_eq!(BytesMut::from(page), &[3; 64][..]);
1969
1970 let s = ByteString::from_static("string");
1971 assert_eq!(BytePage::from(&s), "string");
1972 }
1973
1974 #[test]
1980 fn append_storage_page() {
1981 let mut pages = BytePages::new(BytePageSize::Size4);
1983 let mut buf = BytesMut::with_capacity(64);
1984 buf.extend_from_slice(b"a");
1985 pages.append(buf);
1986 pages.extend_from_slice(b"b");
1987 assert_eq!(pages.num_pages(), 1);
1988 assert_eq!(pages.freeze(), "ab");
1989
1990 let mut buf = BytesMut::with_capacity(64);
1992 let cap = buf.capacity();
1993 buf.resize(cap, b'x');
1994 pages.append(buf);
1995 let page = BytePage::from(BytesMut::copy_from_slice([b'y'; 64]));
1996 let shared = page.clone();
1997 pages.append(page);
1998 pages.extend_from_slice(b"z");
1999 assert_eq!(pages.num_pages(), 3);
2000 assert_eq!(pages.len(), cap + 65);
2001 assert_eq!(shared, &[b'y'; 64][..]);
2002 }
2003
2004 fn mixed_pages() -> BytePages {
2006 let mut pages = BytePages::new(BytePageSize::Size4);
2007 pages.extend_from_slice(b"current");
2008 pages.prepend(Bytes::copy_from_slice(&[b'b'; 64]));
2009 pages.prepend(Bytes::copy_from_slice(b"ab"));
2010 assert!(pages.pages()[0].is_inline());
2011 pages
2012 }
2013
2014 #[test]
2020 fn iter_pages() {
2021 let pages = BytePages::default();
2022 assert_eq!(pages.iter().count(), 0);
2023
2024 let pages = mixed_pages();
2025 let chunks: Vec<&[u8]> = pages.iter().collect();
2026 assert_eq!(chunks, [&b"ab"[..], &[b'b'; 64][..], &b"current"[..]]);
2027 assert_eq!(chunks.len(), pages.num_pages());
2028
2029 let ptrs: Vec<*const u8> = pages.iter().map(<[u8]>::as_ptr).collect();
2031 let moved = Box::new(pages);
2032 let moved_ptrs: Vec<*const u8> = moved.iter().map(<[u8]>::as_ptr).collect();
2033 assert_eq!(ptrs, moved_ptrs);
2034
2035 let mut pages = BytePages::new(BytePageSize::Size4);
2037 pages.extend_from_slice(b"data");
2038 pages.prepend(Bytes::copy_from_slice(b"ab"));
2039 pages.advance_to(6);
2040 assert_eq!(pages.iter().count(), 0);
2041 assert_eq!(pages.num_pages(), 0);
2042 }
2043
2044 #[test]
2050 fn advance_to_pages() {
2051 let mut pages = mixed_pages();
2052 let len = pages.len();
2053 pages.advance_to(0);
2054 assert_eq!(pages.len(), len);
2055
2056 pages.advance_to(2);
2058 assert_eq!(pages.len(), len - 2);
2059 assert_eq!(pages.num_pages(), 2);
2060 assert_eq!(pages.iter().next().unwrap(), &[b'b'; 64][..]);
2061
2062 pages.advance_to(60);
2064 assert_eq!(pages.len(), 11);
2065 assert_eq!(pages.num_pages(), 2);
2066 let chunks: Vec<&[u8]> = pages.iter().collect();
2067 assert_eq!(chunks, [&b"bbbb"[..], &b"current"[..]]);
2068
2069 pages.advance_to(6);
2071 assert_eq!(pages.len(), 5);
2072 assert_eq!(pages.num_pages(), 1);
2073 assert_eq!(pages.iter().next().unwrap(), b"rrent");
2074
2075 let ptr = pages.iter().next().unwrap().as_ptr();
2077 pages.advance_to(5);
2078 assert!(pages.is_empty());
2079 assert_eq!(pages.num_pages(), 0);
2080 pages.extend_from_slice(b"next");
2081 assert_eq!(pages.num_pages(), 1);
2082 assert_eq!(pages.iter().next().unwrap().as_ptr(), ptr.wrapping_add(5));
2083 assert_eq!(pages.freeze(), "next");
2084 }
2085
2086 #[test]
2092 fn move_to_keeps_pages() {
2093 let mut src = mixed_pages();
2095 let ptrs: Vec<*const u8> = src
2096 .iter()
2097 .filter(|s| s.len() > 2)
2098 .map(<[u8]>::as_ptr)
2099 .collect();
2100 let mut dst = BytePages::new(BytePageSize::Size16);
2101 src.move_to(&mut dst);
2102 assert!(src.is_empty());
2103 assert_eq!(src.num_pages(), 0);
2104 assert_eq!(dst.page_size(), BytePageSize::Size16);
2105 assert_eq!(dst.num_pages(), 3);
2106 assert_eq!(dst.len(), 73);
2107 let moved: Vec<*const u8> = dst
2108 .iter()
2109 .filter(|s| s.len() > 2)
2110 .map(<[u8]>::as_ptr)
2111 .collect();
2112 assert_eq!(ptrs, moved);
2113
2114 let mut dst = BytePages::new(BytePageSize::Size4);
2118 dst.extend_from_slice(b"first");
2119 dst.prepend(Bytes::copy_from_slice(b"0"));
2120 let mut src = mixed_pages();
2121 src.move_to(&mut dst);
2122 let chunks: Vec<&[u8]> = dst.iter().collect();
2123 assert_eq!(
2124 chunks,
2125 [
2126 &b"0"[..],
2127 &b"first"[..],
2128 &b"ab"[..],
2129 &[b'b'; 64][..],
2130 &b"current"[..]
2131 ]
2132 );
2133 assert_eq!(dst.len(), 79);
2134 dst.extend_from_slice(b"last");
2135 assert_eq!(dst.num_pages(), 6);
2136
2137 let mut src = BytePages::default();
2139 src.move_to(&mut dst);
2140 assert_eq!(dst.num_pages(), 6);
2141 }
2142
2143 #[test]
2153 fn move_to_copies_small_current() {
2154 let mut src = BytePages::new(BytePageSize::Size8);
2155 src.extend_from_slice(b"hello");
2156 let src_ptr = src.iter().next().unwrap().as_ptr();
2157 let mut dst = BytePages::new(BytePageSize::Size8);
2158 dst.extend_from_slice(b"head ");
2159 let dst_ptr = dst.iter().next().unwrap().as_ptr();
2160 src.move_to(&mut dst);
2161 assert!(src.is_empty());
2162 assert_eq!(src.num_pages(), 0);
2163 assert_eq!(dst.num_pages(), 1);
2164 assert_eq!(dst.iter().next().unwrap(), b"head hello");
2165 assert_eq!(dst.iter().next().unwrap().as_ptr(), dst_ptr);
2166 src.extend_from_slice(b"again");
2167 assert_eq!(src.iter().next().unwrap().as_ptr(), src_ptr);
2168
2169 let mut src = BytePages::new(BytePageSize::Size8);
2171 src.extend_from_slice(b"hello");
2172 let src_ptr = src.iter().next().unwrap().as_ptr();
2173 let mut dst = BytePages::new(BytePageSize::Size8);
2174 src.move_to(&mut dst);
2175 assert_eq!(dst.num_pages(), 1);
2176 assert_eq!(dst.iter().next().unwrap().as_ptr(), src_ptr);
2177
2178 let mut src = BytePages::new(BytePageSize::Size8);
2180 src.extend_from_slice(b"hello");
2181 let src_ptr = src.iter().next().unwrap().as_ptr();
2182 let mut dst = BytePages::new(BytePageSize::Size4);
2183 dst.extend_from_slice(b"a");
2184 let spare = dst.spare();
2185 dst.extend_from_slice(&vec![b'a'; spare - 3]);
2186 src.move_to(&mut dst);
2187 let chunks: Vec<&[u8]> = dst.iter().collect();
2188 assert_eq!(chunks.len(), 2);
2189 assert_eq!(chunks[0].len(), spare - 2);
2190 assert_eq!(chunks[1], b"hello");
2191 assert_eq!(chunks[1].as_ptr(), src_ptr);
2192
2193 let mut src = BytePages::new(BytePageSize::Size8);
2195 src.extend_from_slice(&[b'x'; APPEND_COPY_LIMIT]);
2196 let src_ptr = src.iter().next().unwrap().as_ptr();
2197 let mut dst = BytePages::new(BytePageSize::Size16);
2198 dst.extend_from_slice(b"head");
2199 src.move_to(&mut dst);
2200 let chunks: Vec<&[u8]> = dst.iter().collect();
2201 assert_eq!(chunks.len(), 2);
2202 assert_eq!(chunks[1].as_ptr(), src_ptr);
2203
2204 let mut src = BytePages::new(BytePageSize::Size4);
2206 src.extend_from_slice(b"hello");
2207 let src_ptr = src.iter().next().unwrap().as_ptr();
2208 let mut dst = BytePages::new(BytePageSize::Size8);
2209 dst.extend_from_slice(b"head");
2210 src.move_to(&mut dst);
2211 let chunks: Vec<&[u8]> = dst.iter().collect();
2212 assert_eq!(chunks, [&b"head"[..], &b"hello"[..]]);
2213 assert_eq!(chunks[1].as_ptr(), src_ptr);
2214
2215 for (cap, copied) in [(10_000, true), (1000, false)] {
2217 let mut buf = BytesMut::with_capacity(cap);
2218 buf.extend_from_slice(b"hello");
2219 let mut src = BytePages::new(BytePageSize::Size8);
2220 src.append(buf);
2221 let st = src.current.as_ref().unwrap();
2222 assert_eq!(st.page_size(), BytePageSize::Unset);
2223 assert_eq!(st.capacity() >= 8 * 1024, copied);
2224 let mut dst = BytePages::new(BytePageSize::Size8);
2225 dst.extend_from_slice(b"head");
2226 src.move_to(&mut dst);
2227 assert!(src.is_empty());
2228 let chunks: Vec<&[u8]> = dst.iter().collect();
2229 if copied {
2230 assert_eq!(chunks, [&b"headhello"[..]]);
2231 } else {
2232 assert_eq!(chunks, [&b"head"[..], &b"hello"[..]]);
2233 }
2234 }
2235
2236 let mut buf = BytesMut::with_capacity(20_000);
2238 buf.extend_from_slice(&[b'x'; APPEND_COPY_LIMIT]);
2239 let mut src = BytePages::new(BytePageSize::Size8);
2240 src.append(buf);
2241 assert_eq!(
2242 src.current.as_ref().unwrap().page_size(),
2243 BytePageSize::Unset
2244 );
2245 let src_ptr = src.iter().next().unwrap().as_ptr();
2246 let mut dst = BytePages::new(BytePageSize::Size16);
2247 dst.extend_from_slice(b"head");
2248 src.move_to(&mut dst);
2249 let chunks: Vec<&[u8]> = dst.iter().collect();
2250 assert_eq!(chunks.len(), 2);
2251 assert_eq!(chunks[1].as_ptr(), src_ptr);
2252 }
2253
2254 #[test]
2259 fn advance_to_vec_page() {
2260 let mut pages = BytePages::default();
2261 pages.prepend(b"hello world".to_vec());
2262 pages.advance_to(6);
2263 assert_eq!(pages.len(), 5);
2264 assert_eq!(pages.freeze(), "world");
2265 }
2266
2267 #[test]
2272 #[should_panic(expected = "cannot advance past the end of the buffer")]
2273 fn advance_to_past_end() {
2274 let mut pages = mixed_pages();
2275 pages.advance_to(pages.len() + 1);
2276 }
2277}