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 {
41 assert!(size != BytePageSize::Unset, "Page size cannot be Unset");
42
43 let cached = CACHE
45 .try_with(|c| {
46 let mut cache = c.take()?;
47 let item = cache.pop();
48 c.set(Some(cache));
49 item
50 })
51 .ok()
52 .flatten();
53
54 let st = if let Some(mut item) = cached {
55 item.size = size;
56 item
57 } else {
58 Box::new(Inner {
59 size,
60 len: 0,
61 pages: VecDeque::with_capacity(8),
62 })
63 };
64
65 BytePages {
66 st: Some(st),
67 current: None,
68 }
69 }
70
71 fn pages(&self) -> &VecDeque<BytePage> {
72 &self.st.as_ref().unwrap().pages
73 }
74
75 fn push_front(&mut self, page: BytePage) {
78 let st = self.st.as_mut().unwrap();
79 st.len += page.len();
80 st.pages.push_front(page);
81 }
82
83 fn pop_front(&mut self) -> Option<BytePage> {
84 let st = self.st.as_mut().unwrap();
85 let page = st.pages.pop_front()?;
86 st.len -= page.len();
87 Some(page)
88 }
89
90 fn push_back(&mut self, page: BytePage) {
91 let st = self.st.as_mut().unwrap();
92 st.len += page.len();
93 let pages = &mut st.pages;
94 pages.push_back(page);
95
96 #[cfg(feature = "overuse")]
97 if pages.len() == 128 {
98 log::debug!(
99 "Number of pages {}\n{:?}",
100 pages.len(),
101 backtrace::Backtrace::new()
102 );
103 }
104 }
105
106 pub fn page_size(&self) -> BytePageSize {
108 self.st.as_ref().unwrap().size
109 }
110
111 pub fn set_page_size(&mut self, size: BytePageSize) {
117 assert!(size != BytePageSize::Unset, "Page size cannot be Unset");
118 self.st.as_mut().unwrap().size = size;
119 }
120
121 pub fn prepend<T>(&mut self, buf: T) -> bool
125 where
126 BytePage: From<T>,
127 {
128 let p = BytePage::from(buf);
129 if p.is_empty() {
130 false
131 } else {
132 self.push_front(p);
133 true
134 }
135 }
136
137 pub fn append<T>(&mut self, buf: T)
147 where
148 BytePage: From<T>,
149 {
150 let p = BytePage::from(buf);
151 if !p.is_empty() {
152 if self.current_len() == 0 {
153 match p.into_storage() {
154 Ok(st) => {
155 self.current = Some(st);
156 }
157 Err(page) => {
158 self.push_back(page);
160 }
161 }
162 } else if p.len() <= APPEND_COPY_LIMIT {
163 self.put_slice(p.as_ref());
164 } else {
165 if let Some(st) = self.current.as_mut() {
167 let head = st.split_to(st.len());
168 self.push_back(<BytePage as From<Bytes>>::from(Bytes { storage: head }));
169 }
170 self.push_back(p);
171 }
172 }
173 }
174
175 #[inline]
176 pub fn extend_from_slice(&mut self, extend: &[u8]) {
182 self.put_slice(extend);
183 }
184
185 #[inline]
186 pub fn len(&self) -> usize {
188 self.st.as_ref().unwrap().len + self.current_len()
189 }
190
191 fn current_len(&self) -> usize {
192 self.current
193 .as_ref()
194 .map(StorageVec::len)
195 .unwrap_or_default()
196 }
197
198 fn spare(&self) -> usize {
200 self.current
201 .as_ref()
202 .map(StorageVec::remaining)
203 .unwrap_or_default()
204 }
205
206 #[inline]
207 pub fn is_empty(&self) -> bool {
209 self.len() == 0
210 }
211
212 #[inline]
213 pub fn num_pages(&self) -> usize {
215 if self.current_len() == 0 {
216 self.pages().len()
217 } else {
218 self.pages().len() + 1
219 }
220 }
221
222 pub fn take(&mut self) -> Option<BytePage> {
228 if let Some(page) = self.pop_front() {
229 Some(page)
230 } else if self.current_len() == 0 {
231 None
232 } else {
233 self.current.take().map(BytePage::from)
234 }
235 }
236
237 pub fn iter(&self) -> impl Iterator<Item = &[u8]> {
243 self.pages().iter().map(BytePage::as_ref).chain(
244 self.current
245 .as_ref()
246 .map(StorageVec::as_ref)
247 .filter(|s| !s.is_empty()),
248 )
249 }
250
251 pub fn advance_to(&mut self, mut cnt: usize) {
260 assert!(
261 cnt <= self.len(),
262 "cannot advance past the end of the buffer, cnt:{cnt} len:{}",
263 self.len()
264 );
265
266 while cnt > 0
267 && let Some(mut page) = self.pop_front()
268 {
269 if cnt < page.len() {
270 page.advance_to(cnt);
271 self.push_front(page);
272 return;
273 }
274 cnt -= page.len();
275 }
276 if cnt > 0
277 && let Some(st) = self.current.as_mut()
278 {
279 unsafe { st.set_start(cnt) };
281 }
282 }
283
284 #[inline]
285 pub fn copy_to(&self, pages: &mut BytePages) {
292 for p in self.pages() {
293 pages.append(p.clone());
294 }
295
296 if let Some(st) = &self.current {
297 pages.append(Bytes {
300 storage: st.shallow_freeze(),
301 });
302 }
303 }
304
305 pub fn move_to(&mut self, pages: &mut BytePages) {
313 if self.is_empty() {
314 return;
315 }
316
317 if let Some(st) = pages.current.as_mut()
318 && st.len() != 0
319 {
320 let head = st.split_to(st.len());
321 pages.push_back(<BytePage as From<Bytes>>::from(Bytes { storage: head }));
322 }
323
324 let src = self.st.as_mut().unwrap();
325 let dst = pages.st.as_mut().unwrap();
326 if dst.pages.is_empty() {
327 mem::swap(&mut src.pages, &mut dst.pages);
328 dst.len = mem::take(&mut src.len);
329 } else {
330 while let Some(page) = self.pop_front() {
331 pages.push_back(page);
332 }
333 }
334
335 if self.current_len() != 0
336 && let Some(st) = self.current.take()
337 {
338 pages.push_back(BytePage::from(st));
339 }
340 }
341
342 #[must_use]
350 pub fn split_to(&mut self, at: usize) -> BytePages {
351 let mut pages = BytePages::new(self.page_size());
352 self.split_into(at, &mut pages);
353 pages
354 }
355
356 pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
364 while let Some(mut page) = self.pop_front() {
365 let len = cmp::min(page.len(), at);
366 to.append(page.split_to(len));
367
368 if !page.is_empty() {
369 self.push_front(page);
370 return;
371 }
372 at -= len;
373 }
374 if at > 0
375 && let Some(mut st) = self.current.take()
376 {
377 if at < st.len() {
378 to.append(Bytes {
380 storage: st.split_to(at),
381 });
382 self.current = Some(st);
383 } else if st.len() == 0 {
384 self.current = Some(st);
385 } else {
386 to.append(BytePage::from(st));
387 }
388 }
389 }
390
391 #[inline]
393 pub fn clear(&mut self) {
394 while self.take().is_some() {}
395 }
396
397 #[inline]
399 #[must_use]
400 pub fn freeze(&mut self) -> Bytes {
401 let pages = self.num_pages();
402 if pages == 0 || self.is_empty() {
403 Bytes::new()
404 } else if pages == 1 {
405 self.take().unwrap().freeze()
406 } else {
407 let mut buf = BytesMut::with_capacity(self.len());
408 while let Some(p) = self.take() {
409 buf.extend_from_slice(&p);
410 }
411 buf.freeze()
412 }
413 }
414
415 #[inline]
416 pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
418 if self.pages().is_empty()
419 && self.current.is_none()
420 && let Some(st) = pages.current.take()
421 {
422 self.current = Some(st);
423 }
424 }
425
426 #[doc(hidden)]
436 #[deprecated(
437 since = "1.10.0",
438 note = "use the `BufMut` methods of `BytePages` instead"
439 )]
440 pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
441 where
442 F: FnOnce(&mut BytesMut) -> R,
443 {
444 let mut buf = BytesMut::new();
445 let res = f(&mut buf);
446 self.append(buf);
447 res
448 }
449
450 fn with_current<F, R>(&mut self, f: F) -> R
451 where
452 F: FnOnce(&mut StorageVec) -> R,
453 {
454 let mut st = self
455 .current
456 .take()
457 .unwrap_or_else(|| StorageVec::sized(self.page_size()));
458 let result = f(&mut st);
459
460 if st.is_full() {
462 self.push_back(BytePage::from(st));
463 } else {
464 self.current = Some(st);
465 }
466
467 result
468 }
469}
470
471impl Drop for BytePages {
472 fn drop(&mut self) {
473 if let Some(mut st) = self.st.take() {
474 st.pages.clear();
475 st.pages.shrink_to(8);
477 st.len = 0;
478 let _ = CACHE.try_with(move |c| {
480 if let Some(mut cache) = c.take() {
481 if cache.len() < CACHE_SIZE {
482 cache.push(st);
483 }
484 c.set(Some(cache));
485 }
486 });
487 }
488 }
489}
490
491impl fmt::Debug for BytePages {
492 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
493 let mut f = fmt.debug_tuple("BytePages");
494 for p in self.pages() {
495 f.field(p);
496 }
497 if let Some(st) = &self.current {
498 f.field(&crate::debug::BsDebug(st.as_ref()));
499 }
500 f.finish()
501 }
502}
503
504impl Default for BytePages {
505 fn default() -> Self {
506 BytePages::new(BytePageSize::Size16)
507 }
508}
509
510impl BufMut for BytePages {
514 #[inline]
515 fn remaining_mut(&self) -> usize {
516 usize::MAX - self.len()
517 }
518
519 #[inline]
520 unsafe fn advance_mut(&mut self, cnt: usize) {
521 if cnt == 0 {
522 return;
523 }
524 let spare = self.spare();
525 assert!(
526 cnt <= spare,
527 "cannot advance past the current page: {cnt:?} <= {spare:?}"
528 );
529 let st = self.current.as_mut().unwrap();
530 st.set_len(st.len() + cnt);
531 }
532
533 #[inline]
534 fn chunk_mut(&mut self) -> &mut UninitSlice {
535 if self.spare() == 0 {
536 if let Some(st) = self.current.take() {
537 self.push_back(BytePage::from(st));
538 }
539 self.current = Some(StorageVec::sized(self.page_size()));
540 }
541 self.current.as_mut().unwrap().spare_mut()
543 }
544
545 fn put<T: Buf>(&mut self, mut src: T)
546 where
547 Self: Sized,
548 {
549 while src.has_remaining() {
550 let chunk = src.chunk();
551 let len = chunk.len();
552 self.put_slice(chunk);
553 src.advance(len);
554 }
555 }
556
557 fn put_slice(&mut self, mut src: &[u8]) {
558 while !src.is_empty() {
559 let amount = self.with_current(|st| st.put_slice_partial(src));
560
561 src = &src[amount..];
562 }
563 }
564
565 #[inline]
566 fn put_u8(&mut self, n: u8) {
567 self.with_current(|st| st.put_u8(n));
568 }
569
570 #[inline]
571 fn put_i8(&mut self, n: i8) {
572 self.put_u8(n as u8);
573 }
574}
575
576impl Clone for BytePages {
577 fn clone(&self) -> Self {
578 let size = self.page_size();
579 let mut pages = BytePages::new(size);
580 self.copy_to(&mut pages);
581 pages
582 }
583}
584
585impl io::Write for BytePages {
586 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
587 self.put_slice(src);
588 Ok(src.len())
589 }
590
591 fn flush(&mut self) -> Result<(), io::Error> {
592 Ok(())
593 }
594}
595
596impl From<BytePages> for Bytes {
597 fn from(mut pages: BytePages) -> Bytes {
599 pages.freeze()
600 }
601}
602
603impl From<BytePages> for BytesMut {
604 fn from(mut pages: BytePages) -> BytesMut {
607 if pages.num_pages() == 1 {
608 return BytesMut::from(pages.take().unwrap());
609 }
610
611 let mut buf = BytesMut::with_capacity(pages.len());
612 while let Some(p) = pages.take() {
613 buf.extend_from_slice(&p);
614 }
615 buf
616 }
617}
618
619pub struct BytePage {
621 inner: StorageType,
622}
623
624enum StorageType {
625 Bytes(Bytes),
626 Storage(StorageVec),
627 Vec(Vec<u8>),
628}
629
630impl BytePage {
631 #[inline]
632 pub fn len(&self) -> usize {
634 self.as_ref().len()
635 }
636
637 #[inline]
638 pub fn is_empty(&self) -> bool {
640 self.len() == 0
641 }
642
643 #[inline]
644 pub unsafe fn as_ptr(&self) -> *const u8 {
653 unsafe {
654 match &self.inner {
655 StorageType::Bytes(b) => b.storage.as_ptr(),
656 StorageType::Storage(b) => b.as_ptr(),
657 StorageType::Vec(b) => b.as_ptr(),
658 }
659 }
660 }
661
662 #[inline]
663 #[doc(hidden)]
664 pub fn info(&self) -> crate::info::PageKind {
666 match &self.inner {
667 StorageType::Bytes(_) => crate::info::PageKind::Bytes,
668 StorageType::Storage(_) => crate::info::PageKind::Storage,
669 StorageType::Vec(_) => crate::info::PageKind::Vec,
670 }
671 }
672
673 #[inline]
674 #[doc(hidden)]
675 pub fn is_inline(&self) -> bool {
680 matches!(&self.inner, StorageType::Bytes(b) if b.is_inline())
681 }
682
683 #[must_use]
691 pub fn split_to(&mut self, at: usize) -> BytePage {
692 match &mut self.inner {
693 StorageType::Bytes(b) => {
694 let buf = b.split_to(cmp::min(at, b.len()));
695 BytePage {
696 inner: StorageType::Bytes(buf),
697 }
698 }
699 StorageType::Storage(_) => {
700 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
701 if let StorageType::Storage(st) = inner {
702 self.inner = StorageType::Bytes(Bytes {
703 storage: st.freeze(),
704 });
705 self.split_to(at)
706 } else {
707 unreachable!()
708 }
709 }
710 StorageType::Vec(_) => {
711 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
712 if let StorageType::Vec(b) = inner {
713 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
714 self.split_to(at)
715 } else {
716 unreachable!()
717 }
718 }
719 }
720 }
721
722 #[inline]
732 pub fn advance_to(&mut self, cnt: usize) {
733 match &mut self.inner {
734 StorageType::Bytes(b) => b.advance_to(cnt),
735 StorageType::Storage(b) => unsafe { b.set_start(cnt) },
736 StorageType::Vec(b) => {
737 assert!(
738 cnt <= b.len(),
739 "cannot advance past the end of the buffer, cnt:{cnt} len:{}",
740 b.len()
741 );
742 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
743 }
744 }
745 }
746
747 #[inline]
749 #[must_use]
750 pub fn freeze(self) -> Bytes {
751 match self.inner {
752 StorageType::Bytes(b) => b,
753 StorageType::Storage(st) => Bytes {
754 storage: st.freeze(),
755 },
756 StorageType::Vec(v) => Bytes::from(v),
757 }
758 }
759
760 fn into_storage(self) -> Result<StorageVec, Self> {
761 if let StorageType::Storage(st) = self.inner {
762 if !st.is_full() && st.is_unique() {
764 Ok(st)
765 } else {
766 Err(Self {
767 inner: StorageType::Storage(st),
768 })
769 }
770 } else {
771 Err(self)
772 }
773 }
774}
775
776impl Clone for BytePage {
777 fn clone(&self) -> Self {
778 let inner = match &self.inner {
779 StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
780 StorageType::Storage(st) => StorageType::Bytes(Bytes {
783 storage: st.shallow_freeze(),
784 }),
785 StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
786 };
787
788 Self { inner }
789 }
790}
791
792impl AsRef<[u8]> for BytePage {
793 #[inline]
794 fn as_ref(&self) -> &[u8] {
795 match &self.inner {
796 StorageType::Bytes(b) => b.as_ref(),
797 StorageType::Storage(b) => b.as_ref(),
798 StorageType::Vec(b) => b.as_ref(),
799 }
800 }
801}
802
803impl Borrow<[u8]> for BytePage {
804 #[inline]
805 fn borrow(&self) -> &[u8] {
806 self.as_ref()
807 }
808}
809
810impl From<Bytes> for BytePage {
811 fn from(buf: Bytes) -> Self {
812 BytePage {
813 inner: StorageType::Bytes(buf),
814 }
815 }
816}
817
818impl<'a> From<&'a Bytes> for BytePage {
819 fn from(buf: &'a Bytes) -> Self {
820 BytePage {
821 inner: StorageType::Bytes(buf.clone()),
822 }
823 }
824}
825
826impl From<BytesMut> for BytePage {
827 fn from(buf: BytesMut) -> Self {
828 BytePage {
829 inner: StorageType::Storage(buf.storage),
830 }
831 }
832}
833
834impl From<ByteString> for BytePage {
835 fn from(s: ByteString) -> Self {
836 s.into_bytes().into()
837 }
838}
839
840impl<'a> From<&'a ByteString> for BytePage {
841 fn from(s: &'a ByteString) -> Self {
842 s.clone().into_bytes().into()
843 }
844}
845
846impl From<StorageVec> for BytePage {
847 fn from(buf: StorageVec) -> Self {
848 BytePage {
849 inner: StorageType::Storage(buf),
850 }
851 }
852}
853
854impl From<Vec<u8>> for BytePage {
855 fn from(buf: Vec<u8>) -> Self {
856 BytePage {
857 inner: StorageType::Vec(buf),
858 }
859 }
860}
861
862impl From<&'static str> for BytePage {
863 fn from(buf: &'static str) -> Self {
864 Bytes::from_static(buf.as_bytes()).into()
865 }
866}
867
868impl From<&'static [u8]> for BytePage {
869 fn from(buf: &'static [u8]) -> Self {
870 Bytes::from_static(buf).into()
871 }
872}
873
874impl<const N: usize> From<&'static [u8; N]> for BytePage {
875 fn from(buf: &'static [u8; N]) -> Self {
876 Bytes::from_static(buf).into()
877 }
878}
879
880impl From<BytePage> for Bytes {
881 fn from(page: BytePage) -> Self {
882 match page.inner {
883 StorageType::Bytes(b) => b,
884 StorageType::Storage(storage) => BytesMut { storage }.freeze(),
885 StorageType::Vec(v) => Bytes::copy_from_slice(&v),
886 }
887 }
888}
889
890impl From<BytePage> for BytesMut {
891 fn from(page: BytePage) -> Self {
892 match page.inner {
893 StorageType::Bytes(b) => b.into(),
894 StorageType::Storage(storage) => {
896 if storage.is_unique() {
897 BytesMut { storage }
898 } else {
899 BytesMut::copy_from_slice(storage.as_ref())
900 }
901 }
902 StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
903 }
904 }
905}
906
907impl PartialEq for BytePage {
908 fn eq(&self, other: &BytePage) -> bool {
909 self.as_ref() == other.as_ref()
910 }
911}
912
913impl_partial_eq!(BytePage);
914
915impl_read!(BytePage);
916
917impl ops::Deref for BytePage {
918 type Target = [u8];
919
920 #[inline]
921 fn deref(&self) -> &[u8] {
922 self.as_ref()
923 }
924}
925
926impl fmt::Debug for BytePage {
927 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
928 fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
929 }
930}
931
932#[cfg(test)]
933mod tests {
934 use rand::Rng;
935
936 use super::*;
937
938 #[test]
939 #[allow(clippy::op_ref, clippy::cmp_owned)]
940 fn page_eq_and_read() {
941 use std::io::Read;
942
943 let mut page = BytePage::from(Vec::from(&b"hello"[..]));
944 assert_eq!(page, b"hello"[..]);
945 assert_eq!(page, *b"hello");
946 assert_eq!(page, b"hello");
947 assert_eq!(page, &b"hello"[..]);
948 assert_eq!(page, "hello");
949 assert_eq!(page, *"hello");
950 assert_eq!(page, b"hello".to_vec());
951 assert_eq!(page, String::from("hello"));
952 assert_eq!(b"hello"[..], page);
953 assert_eq!(*b"hello", page);
954 assert_eq!(b"hello", page);
955 assert_eq!(&b"hello"[..], page);
956 assert_eq!("hello", page);
957 assert_eq!(*"hello", page);
958 assert_eq!(b"hello".to_vec(), page);
959 assert_eq!(String::from("hello"), page);
960 assert_ne!(page, "hell");
961
962 let mut buf = [0u8; 3];
963 assert_eq!(page.read(&mut buf).unwrap(), 3);
964 assert_eq!(&buf, b"hel");
965 assert_eq!(page, "lo");
966 assert_eq!(page.read(&mut buf).unwrap(), 2);
967 assert_eq!(page.read(&mut buf).unwrap(), 0);
968 assert!(page.is_empty());
969 }
970
971 #[test]
972 fn page_info() {
973 use crate::info::PageKind;
974
975 let p = BytePage::from(Bytes::copy_from_slice(&[1; 64]));
976 assert_eq!(p.info(), PageKind::Bytes);
977 let p = BytePage::from(BytesMut::copy_from_slice(&[1; 64][..]));
978 assert_eq!(p.info(), PageKind::Storage);
979 let p = BytePage::from(vec![1; 64]);
980 assert_eq!(p.info(), PageKind::Vec);
981 assert!(!p.is_inline());
982
983 assert!(BytePage::from(Bytes::copy_from_slice(&[1; 4])).is_inline());
984 assert!(!BytePage::from(Bytes::copy_from_slice(&[1; 64])).is_inline());
985 assert!(!BytePage::from(BytesMut::copy_from_slice(&[1; 4][..])).is_inline());
986 }
987
988 #[test]
989 fn append_copies_small_and_splits_for_large() {
990 let cap = BytePageSize::Size16.capacity();
991 let mut pages = BytePages::new(BytePageSize::Size16);
992 pages.extend_from_slice(b"head\r\n");
993
994 pages.append(Bytes::copy_from_slice(&[1; APPEND_COPY_LIMIT]));
996 assert_eq!(pages.num_pages(), 1);
997 assert_eq!(pages.current_len(), 6 + APPEND_COPY_LIMIT);
998
999 let body = Bytes::copy_from_slice(&[2; APPEND_COPY_LIMIT + 1]);
1001 let body_ptr = body.as_ptr();
1002 pages.append(body.clone());
1003 assert_eq!(pages.num_pages(), 2);
1004 assert_eq!(pages.current_len(), 0);
1005 assert_eq!(pages.spare(), cap - 6 - APPEND_COPY_LIMIT);
1006
1007 let page_ptr = pages.pages()[0].as_ref().as_ptr();
1009 pages.extend_from_slice(b"\r\n");
1010 assert_eq!(pages.num_pages(), 3);
1011 let tail_ptr = pages.current.as_ref().unwrap().as_ref().as_ptr();
1012 assert_eq!(tail_ptr, page_ptr.wrapping_add(6 + APPEND_COPY_LIMIT));
1013
1014 let mut expected = b"head\r\n".to_vec();
1015 expected.extend_from_slice(&[1; APPEND_COPY_LIMIT]);
1016 expected.extend_from_slice(&body);
1017 expected.extend_from_slice(b"\r\n");
1018 assert_eq!(pages.len(), expected.len());
1019
1020 let first = pages.take().unwrap();
1021 let second = pages.take().unwrap();
1022 assert_eq!(second.as_ref().as_ptr(), body_ptr);
1023 let third = pages.take().unwrap();
1024 assert!(pages.take().is_none());
1025 let data = [first.as_ref(), second.as_ref(), third.as_ref()].concat();
1026 assert_eq!(data, expected);
1027
1028 pages.extend_from_slice(b"x");
1030 pages.append(body);
1031 assert_eq!(pages.take().unwrap().as_ref(), b"x");
1032 assert_eq!(pages.take().unwrap().len(), APPEND_COPY_LIMIT + 1);
1033 assert!(pages.take().is_none());
1034 assert_eq!(pages.num_pages(), 0);
1035 assert_eq!(pages.spare(), cap - 1);
1036 }
1037
1038 #[test]
1039 fn pages() {
1040 let cap = BytePageSize::Size8.capacity();
1041 unsafe {
1042 let mut pages = BytePages::new(BytePageSize::Size8);
1044 assert!(pages.is_empty());
1045 assert_eq!(pages.len(), 0);
1046 assert_eq!(pages.num_pages(), 0);
1047 pages.extend_from_slice(b"b");
1048 assert_eq!(pages.len(), 1);
1049 assert_eq!(pages.num_pages(), 1);
1050 pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
1051 assert_eq!(pages.len(), 9217);
1052 assert_eq!(pages.num_pages(), 2);
1053 assert!(!pages.is_empty());
1054
1055 let mut pgs = BytePages::new(BytePageSize::Size8);
1056 pgs.put_i8(b'a' as i8);
1057 let p = pgs.take().unwrap();
1058 assert_eq!(p.len(), 1);
1059 assert_eq!(p.as_ref(), b"a");
1060
1061 pgs.extend_from_slice("a".repeat(cap - 1).as_bytes());
1062 assert_eq!(pgs.num_pages(), 1);
1063 pgs.put_u8(b'a');
1064 assert_eq!(pgs.num_pages(), 1);
1065 assert!(pgs.current.is_none());
1066
1067 pgs.put_u8(b'a');
1068 assert_eq!(pgs.num_pages(), 2);
1069
1070 pgs.append(Bytes::copy_from_slice("a".repeat(cap).as_bytes()));
1071 assert_eq!(pgs.num_pages(), 3);
1072 assert_eq!(pgs.current_len(), 0);
1073 assert_eq!(pgs.spare(), cap - 1);
1074
1075 let p = pages.take().unwrap();
1077 assert_eq!(p.len(), cap);
1078 let p = pages.take().unwrap();
1079 assert_eq!(p.len(), 9217 - cap);
1080 assert!(!p.is_empty());
1081 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1082 assert_eq!(p.as_ref(), "a".repeat(9217 - cap).as_bytes());
1083 assert!(pages.take().is_none());
1084
1085 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1086 assert_eq!(p.len(), 3);
1087 assert!(!p.is_empty());
1088 assert_eq!(p.as_ref(), b"123");
1089 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1090
1091 let p = BytePage::from(&b"123"[..]);
1092 assert_eq!(p.len(), 3);
1093 assert!(!p.is_empty());
1094 assert_eq!(p.as_ref(), b"123");
1095 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1096
1097 let p = BytePage::from(b"123");
1098 assert_eq!(p.len(), 3);
1099 assert!(!p.is_empty());
1100 assert_eq!(p.as_ref(), b"123");
1101 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1102
1103 let p = BytePage::from("123");
1104 assert_eq!(p.len(), 3);
1105 assert!(!p.is_empty());
1106 assert_eq!(p.as_ref(), b"123");
1107 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1108 assert_eq!(p.freeze(), b"123");
1109
1110 let p = BytePage::from(vec![b'1', b'2', b'3']);
1111 assert_eq!(p.len(), 3);
1112 assert!(!p.is_empty());
1113 assert_eq!(p.as_ref(), b"123");
1114 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
1115 assert_eq!(p.freeze(), b"123");
1116
1117 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1118 p.advance_to(1);
1119 assert_eq!(p.len(), 2);
1120 assert!(!p.is_empty());
1121 assert_eq!(p.as_ref(), b"23");
1122
1123 let mut pages = BytePages::new(BytePageSize::Size8);
1125 pages.extend_from_slice(b"b");
1126 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
1127 let p = pages.take().unwrap();
1128 assert_eq!(p.as_ref(), b"b");
1129
1130 let mut pages = BytePages::new(BytePageSize::Size8);
1131 pages.extend_from_slice(b"a");
1132 pages.append(Bytes::copy_from_slice(b"123"));
1133 pages.push_back(p);
1134 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
1135
1136 assert_eq!(pages.len(), 5);
1137 pages.clear();
1138 assert_eq!(pages.len(), 0);
1139 }
1140 }
1141
1142 fn assert_len(pages: &BytePages) {
1144 let len = pages.pages().iter().map(BytePage::len).sum::<usize>() + pages.current_len();
1145 assert_eq!(pages.len(), len);
1146 assert_eq!(pages.is_empty(), len == 0);
1147 }
1148
1149 #[test]
1150 fn pages_len_tracking() {
1151 let mut rng = rand::rng();
1152 let mut pages = BytePages::new(BytePageSize::Size8);
1153 let mut other = BytePages::new(BytePageSize::Size8);
1154 let mut expected = 0;
1155
1156 let (iters, max) = if cfg!(miri) { (100, 256) } else { (2000, 12 * 1024) };
1157 for _ in 0..iters {
1158 let n = rng.random_range(0..max);
1159 match rng.random_range(0..9) {
1160 0 => {
1161 pages.extend_from_slice(&vec![1; n]);
1162 expected += n;
1163 }
1164 1 => {
1165 pages.append(Bytes::copy_from_slice(&vec![2; n]));
1166 expected += n;
1167 }
1168 2 => {
1169 if pages.prepend(BytesMut::copy_from_slice(vec![3; n])) {
1170 expected += n;
1171 }
1172 }
1173 3 => {
1174 if let Some(p) = pages.take() {
1175 expected -= p.len();
1176 }
1177 }
1178 4 => {
1179 let at = cmp::min(n, expected);
1180 let split = pages.split_to(at);
1181 assert_len(&split);
1182 assert_eq!(split.len(), at);
1183 expected -= at;
1184 }
1185 5 => {
1186 let at = cmp::min(n, expected);
1187 pages.split_into(at, &mut other);
1188 expected -= at;
1189 }
1190 6 => {
1191 other.move_to(&mut pages);
1192 assert_len(&other);
1193 assert!(other.is_empty());
1194 expected = pages.len();
1195 }
1196 7 => {
1197 let mut copy = BytePages::new(BytePageSize::Size8);
1198 pages.copy_to(&mut copy);
1199 assert_len(©);
1200 assert_eq!(copy.len(), expected);
1201 }
1202 _ => {
1203 pages.put_u8(4);
1204 expected += 1;
1205 }
1206 }
1207 assert_len(&pages);
1208 assert_len(&other);
1209 assert_eq!(pages.len(), expected);
1210 }
1211
1212 let len = pages.len();
1213 assert_eq!(pages.freeze().len(), len);
1214 assert_len(&pages);
1215 assert!(pages.is_empty());
1216 pages.extend_from_slice(b"123");
1217 pages.clear();
1218 assert_len(&pages);
1219 assert!(pages.is_empty());
1220 }
1221
1222 #[test]
1223 fn pages_len_after_cache_reuse() {
1224 let mut pages = BytePages::new(BytePageSize::Size8);
1225 pages.append(Bytes::copy_from_slice(&[1; 64]));
1226 pages.append(Bytes::copy_from_slice(&[1; 64]));
1227 drop(pages);
1228
1229 let pages = BytePages::new(BytePageSize::Size8);
1230 assert_len(&pages);
1231 assert!(pages.is_empty());
1232 }
1233
1234 #[test]
1235 fn pages_copy_to_shares_current() {
1236 let mut pages = BytePages::new(BytePageSize::Size8);
1237 pages.put_slice(&[1; 64]);
1238 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1239
1240 let mut copy = BytePages::new(BytePageSize::Size8);
1241 pages.copy_to(&mut copy);
1242 let page = copy.take().unwrap();
1243 assert_eq!(unsafe { page.as_ptr() }, ptr.cast_const());
1244 assert_eq!(page.as_ref(), &[1; 64][..]);
1245
1246 pages.put_slice(&[2; 64]);
1248 assert_eq!(unsafe { pages.current.as_ref().unwrap().as_ptr() }, ptr);
1249 assert_eq!(page.as_ref(), &[1; 64][..]);
1250 assert_eq!(pages.len(), 128);
1251
1252 drop(pages);
1253 assert_eq!(page.as_ref(), &[1; 64][..]);
1254 }
1255
1256 #[test]
1257 fn pages_split_keeps_current_writable() {
1258 let mut pages = BytePages::new(BytePageSize::Size8);
1259 pages.put_slice(&[1; 64]);
1260 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1261 let remaining = pages.spare();
1262
1263 let mut head = pages.split_to(40);
1264 assert_eq!(head.len(), 40);
1265 assert_eq!(pages.len(), 24);
1266 assert_eq!(pages.num_pages(), 1);
1267 assert_eq!(pages.spare(), remaining);
1268
1269 pages.put_slice(&[2; 16]);
1271 assert_eq!(pages.num_pages(), 1);
1272 assert_eq!(
1273 unsafe { pages.current.as_ref().unwrap().as_ptr() },
1274 ptr.wrapping_add(40)
1275 );
1276 let mut expected = vec![1; 24];
1277 expected.extend_from_slice(&[2; 16]);
1278 assert_eq!(&pages.freeze()[..], &expected[..]);
1279 assert_eq!(&head.freeze()[..], &[1; 40][..]);
1280
1281 let mut pages = BytePages::new(BytePageSize::Size8);
1283 pages.put_slice(&[1; 64]);
1284 let mut to = BytePages::new(BytePageSize::Size8);
1285 pages.split_into(2, &mut to);
1286 assert_eq!(&to.freeze()[..], &[1; 2][..]);
1287 assert_eq!(pages.spare(), remaining);
1288 assert_eq!(pages.len(), 62);
1289
1290 let mut pages = BytePages::new(BytePageSize::Size8);
1292 pages.put_slice(&[1; 64]);
1293 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1294 let to = pages.split_to(64);
1295 assert!(pages.is_empty());
1296 assert_eq!(pages.num_pages(), 0);
1297 assert_eq!(to.spare(), remaining);
1298 assert_eq!(unsafe { to.current.as_ref().unwrap().as_ptr() }, ptr);
1299
1300 let mut pages = BytePages::new(BytePageSize::Size8);
1302 let _ = pages.chunk_mut();
1303 let head = pages.split_to(10);
1304 assert!(head.is_empty());
1305 assert_eq!(pages.spare(), remaining + 64);
1306 }
1307
1308 #[test]
1309 fn pages_buf_mut_grows() {
1310 let mut pages = BytePages::new(BytePageSize::Size8);
1311 assert!(pages.has_remaining_mut());
1312 assert_eq!(pages.remaining_mut(), usize::MAX);
1313 unsafe { pages.advance_mut(0) };
1314
1315 let n = pages.chunk_mut().len();
1317 unsafe {
1318 std::ptr::write_bytes(pages.chunk_mut().as_mut_ptr(), 1, n);
1319 pages.advance_mut(n);
1320 }
1321 assert!(pages.chunk_mut().len() > 0);
1322 assert_eq!(pages.num_pages(), 1);
1324 unsafe {
1325 *pages.chunk_mut().as_mut_ptr() = 2;
1326 pages.advance_mut(1);
1327 }
1328 assert_eq!(pages.len(), n + 1);
1329 assert_eq!(pages.remaining_mut(), usize::MAX - n - 1);
1330
1331 let mut pages = BytePages::new(BytePageSize::Size8);
1333 pages.put(&[3u8; 200][..]);
1334 pages.put(Bytes::from_static(b"abcd"));
1335 io::Write::write_all(&mut pages, &[4; 100]).unwrap();
1336 let mut expected = vec![3; 200];
1337 expected.extend_from_slice(b"abcd");
1338 expected.extend_from_slice(&[4; 100]);
1339 assert_eq!(&pages.freeze()[..], &expected[..]);
1340 }
1341
1342 #[test]
1343 #[should_panic(expected = "cannot advance past the current page")]
1344 fn pages_advance_past_current_page() {
1345 let mut pages = BytePages::new(BytePageSize::Size8);
1346 let n = pages.chunk_mut().len();
1347 unsafe { pages.advance_mut(n + 1) };
1348 }
1349
1350 #[test]
1351 #[should_panic(expected = "Page size cannot be Unset")]
1352 fn pages_new_unset() {
1353 let _ = BytePages::new(BytePageSize::Unset);
1354 }
1355
1356 #[test]
1357 #[should_panic(expected = "Page size cannot be Unset")]
1358 fn pages_set_page_size_unset() {
1359 let mut pages = BytePages::new(BytePageSize::Size8);
1360 pages.set_page_size(BytePageSize::Unset);
1361 }
1362
1363 #[test]
1364 fn cached_pages_list_is_shrunk() {
1365 let mut pages = BytePages::new(BytePageSize::Size4);
1366 for _ in 0..200 {
1367 pages.append(Bytes::from_static(b"page"));
1368 }
1369 assert!(pages.pages().capacity() >= 200);
1370 drop(pages);
1371
1372 let pages = BytePages::new(BytePageSize::Size4);
1373 assert!(
1374 pages.pages().capacity() < 200,
1375 "{}",
1376 pages.pages().capacity()
1377 );
1378 }
1379
1380 #[test]
1381 fn pages_into_bytes_single_page() {
1382 let mut pages = BytePages::new(BytePageSize::Size8);
1384 pages.put_slice(&[1; 64]);
1385 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1386 let mut buf = BytesMut::from(pages);
1387 assert_eq!(buf.as_ptr(), ptr.cast_const());
1388 assert_eq!(&buf[..], &[1; 64][..]);
1389 assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
1391 buf.extend_from_slice(&[2; 64]);
1392 assert_eq!(buf.as_ptr(), ptr.cast_const());
1393
1394 let mut pages = BytePages::new(BytePageSize::Size8);
1395 pages.put_slice(&[1; 64]);
1396 let ptr = unsafe { pages.current.as_ref().unwrap().as_ptr() };
1397 let b = Bytes::from(pages);
1398 assert_eq!(b.as_ptr(), ptr.cast_const());
1399 assert_eq!(&b[..], &[1; 64][..]);
1400
1401 let src = Bytes::copy_from_slice(&[3; 64]);
1403 let ptr = src.as_ptr();
1404 let mut pages = BytePages::new(BytePageSize::Size8);
1405 pages.prepend(src);
1406 assert_eq!(BytesMut::from(pages).as_ptr(), ptr);
1407
1408 let src = Bytes::copy_from_slice(&[3; 64]);
1410 let mut pages = BytePages::new(BytePageSize::Size8);
1411 pages.prepend(&src);
1412 let mut buf = BytesMut::from(pages);
1413 assert_ne!(buf.as_ptr(), src.as_ptr());
1414 buf[0] = 4;
1415 assert_eq!(&src[..], &[3; 64][..]);
1416 }
1417
1418 #[test]
1419 fn pages_into_bytes_multiple_pages() {
1420 let mut pages = BytePages::new(BytePageSize::Size8);
1421 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1422 pages.put_slice(&[2; 64]);
1423 assert_eq!(pages.num_pages(), 2);
1424 let buf = BytesMut::from(pages);
1425 assert_eq!(&buf[..64], &[1; 64][..]);
1426 assert_eq!(&buf[64..], &[2; 64][..]);
1427
1428 let mut pages = BytePages::new(BytePageSize::Size8);
1429 pages.prepend(Bytes::copy_from_slice(&[1; 64]));
1430 pages.put_slice(&[2; 64]);
1431 let b = Bytes::from(pages);
1432 assert_eq!(&b[..64], &[1; 64][..]);
1433 assert_eq!(&b[64..], &[2; 64][..]);
1434
1435 assert!(BytesMut::from(BytePages::new(BytePageSize::Size8)).is_empty());
1436 assert!(Bytes::from(BytePages::new(BytePageSize::Size8)).is_empty());
1437 }
1438
1439 #[test]
1440 fn pages_copy_to() {
1441 let mut pages = BytePages::default();
1442 let mut pages2 = BytePages::default();
1443 pages.put_slice(b"456");
1444 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1445 pages.copy_to(&mut pages2);
1446 let p = pages.freeze();
1447 assert_eq!(p, b"123456");
1448 let p2 = pages2.freeze();
1449 assert_eq!(p2, b"123456");
1450
1451 let mut pages = BytePages::default();
1452 let mut pages2 = BytePages::default();
1453 pages.put_slice(b"456");
1454 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1455 pages.copy_to(&mut pages2);
1456 pages.put_u8(b'7');
1457 let p = pages.freeze();
1458 assert_eq!(p, b"1234567");
1459 let p2 = pages2.freeze();
1460 assert_eq!(p2, b"123456");
1461
1462 let mut pages = BytePages::default();
1463 pages.put_slice(b"456");
1464 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1465 let mut pages2 = pages.clone();
1466 pages.put_u8(b'7');
1467 let p = pages.freeze();
1468 assert_eq!(p, b"1234567");
1469 let p2 = pages2.freeze();
1470 assert_eq!(p2, b"123456");
1471 }
1472
1473 #[test]
1474 fn pages_methods() {
1475 let mut pages = BytePages::default();
1477 pages.put_slice(b"456");
1478 pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
1479 let mut pages2 = pages.split_to(1);
1480 let p = pages.freeze();
1481 assert_eq!(p, b"23456");
1482 let p2 = pages2.freeze();
1483 assert_eq!(p2, b"1");
1484
1485 let mut pages = BytePages::default();
1486 pages.put_slice(b"456");
1487 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
1488 let mut pages2 = pages.split_to(4);
1489 let p = pages.freeze();
1490 assert_eq!(p, b"56");
1491 let p2 = pages2.freeze();
1492 assert_eq!(p2, b"1234");
1493
1494 let mut pages = BytePages::default();
1496 pages.put_slice(b"456");
1497 pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
1498 let mut pages2 = BytePages::default();
1499 pages.split_into(1, &mut pages2);
1500 let p = pages.freeze();
1501 assert_eq!(p, b"23456");
1502 let p2 = pages2.freeze();
1503 assert_eq!(p2, b"1");
1504
1505 let mut pages = BytePages::default();
1507 #[allow(deprecated)]
1508 pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
1509 assert_eq!(pages.len(), 3);
1510 let p = pages.freeze();
1511 assert_eq!(p, b"123");
1512
1513 let data = rand::rng()
1514 .sample_iter(&rand::distr::Alphanumeric)
1515 .take(65_536)
1516 .map(char::from)
1517 .collect::<String>();
1518
1519 let mut pages = BytePages::default();
1520 #[allow(deprecated)]
1521 pages.with_bytes_mut(|buf| buf.extend_from_slice(data.as_bytes()));
1522 assert_eq!(pages.len(), 65_536);
1523 let p = pages.freeze();
1524 assert_eq!(p, data.as_bytes());
1525
1526 let page = BytePage::from(Bytes::copy_from_slice(b"123"));
1528 assert_eq!(page, b"123");
1529 assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
1530 let b = Bytes::from(page);
1531 assert_eq!(b, b"123");
1532 }
1533
1534 #[test]
1535 fn page_clone() {
1536 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
1538 let p2 = p.clone();
1539 assert_eq!(p, p2);
1540
1541 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1543 if let StorageType::Storage(ref mut st) = p.inner {
1544 assert!(st.is_unique());
1545 } else {
1546 panic!()
1547 }
1548 let p2 = p.clone();
1549 assert_eq!(p, p2);
1550 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1552 if let StorageType::Storage(st) = p.inner {
1553 assert!(st.is_unique());
1554 } else {
1555 panic!()
1556 }
1557
1558 let mut p = BytePage::from(BytesMut::copy_from_slice([b'1'; 64]));
1559 let p2 = p.clone();
1560 assert_eq!(p, p2);
1561 assert!(matches!(p2.inner, StorageType::Bytes(_)));
1562 if let StorageType::Storage(ref mut st) = p.inner {
1563 assert!(!st.is_unique());
1564 } else {
1565 panic!()
1566 }
1567 drop(p2);
1568 if let StorageType::Storage(st) = p.inner {
1569 assert!(st.is_unique());
1570 } else {
1571 panic!()
1572 }
1573
1574 let p = BytePage::from(vec![b'1', b'2', b'3']);
1576 let p2 = p.clone();
1577 assert_eq!(p, p2);
1578 if let StorageType::Bytes(_) = p2.inner {
1579 } else {
1580 panic!()
1581 }
1582 }
1583
1584 #[test]
1585 fn page_split_to() {
1586 let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1588 let p2 = p.split_to(1);
1589 assert_eq!(p, b"23");
1590 assert_eq!(p2, b"1");
1591
1592 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1594 let p2 = p.split_to(1);
1595 assert_eq!(p, b"23");
1596 assert_eq!(p2, b"1");
1597
1598 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1600 let p2 = p.split_to(1);
1601 assert_eq!(p, b"23");
1602 assert_eq!(p2, b"1");
1603 }
1604
1605 #[test]
1606 fn page_read() {
1607 use std::io::Read;
1608
1609 let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1610
1611 let mut buf = [0; 10];
1612 assert_eq!(page.read(&mut buf).unwrap(), 3);
1613 assert_eq!(page.len(), 0);
1614 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1615 }
1616
1617 #[test]
1618 fn pages_misc() {
1619 let mut pages = BytePages::new(BytePageSize::Size4);
1620 pages.set_page_size(BytePageSize::Size8);
1621 assert_eq!(pages.page_size(), BytePageSize::Size8);
1622 assert!(!pages.prepend(Bytes::new()));
1623 assert!(pages.prepend(Bytes::from_static(b"a")));
1624
1625 io::Write::write_all(&mut pages, b"bc").unwrap();
1626 io::Write::flush(&mut pages).unwrap();
1627 assert_eq!(pages.freeze(), "abc");
1628
1629 let s = ByteString::from_static("str");
1630 pages.append(&s);
1631 assert_eq!(pages.freeze(), "str");
1632 }
1633
1634 #[test]
1635 fn pages_try_get_current_from() {
1636 let mut src = BytePages::new(BytePageSize::Size4);
1637 src.extend_from_slice(b"data");
1638
1639 let mut dst = BytePages::new(BytePageSize::Size4);
1641 dst.append(Bytes::from_static(b"x"));
1642 dst.try_get_current_from(&mut src);
1643 assert_eq!(src.len(), 4);
1644 assert_eq!(dst.len(), 1);
1645
1646 let mut dst = BytePages::new(BytePageSize::Size4);
1647 dst.try_get_current_from(&mut src);
1648 assert_eq!(src.len(), 0);
1649 assert_eq!(dst.len(), 4);
1650 dst.extend_from_slice(b"!");
1651 assert_eq!(dst.freeze(), "data!");
1652 }
1653
1654 #[test]
1655 fn pages_drop_cache() {
1656 CACHE.with(|c| c.set(Some(Box::default())));
1657 let cached = || {
1658 CACHE.with(|c| {
1659 let cache = c.take().unwrap();
1660 let len = cache.len();
1661 c.set(Some(cache));
1662 len
1663 })
1664 };
1665
1666 let pages: Vec<_> = (0..=CACHE_SIZE)
1668 .map(|_| BytePages::new(BytePageSize::Size4))
1669 .collect();
1670 drop(pages);
1671 assert_eq!(cached(), CACHE_SIZE);
1672
1673 CACHE.with(|c| c.set(Some(Box::default())));
1675 let pages = BytePages::new(BytePageSize::Size4);
1676 let cache = CACHE.with(Cell::take);
1677 drop(pages);
1678 CACHE.with(|c| c.set(cache));
1679 assert_eq!(cached(), 0);
1680 }
1681
1682 #[test]
1683 fn page_conversions() {
1684 let page = BytePage::from(BytesMut::copy_from_slice([1; 64]));
1685 assert_eq!(page.info(), crate::info::PageKind::Storage);
1686 assert_eq!(Bytes::from(page), &[1; 64][..]);
1687
1688 let page = BytePage::from(vec![2; 64]);
1689 assert_eq!(page.info(), crate::info::PageKind::Vec);
1690 assert_eq!(Bytes::from(page), &[2; 64][..]);
1691
1692 let page = BytePage::from(vec![3; 64]);
1693 assert_eq!(BytesMut::from(page), &[3; 64][..]);
1694
1695 let s = ByteString::from_static("string");
1696 assert_eq!(BytePage::from(&s), "string");
1697 }
1698
1699 #[test]
1700 fn append_storage_page() {
1701 let mut pages = BytePages::new(BytePageSize::Size4);
1703 let mut buf = BytesMut::with_capacity(64);
1704 buf.extend_from_slice(b"a");
1705 pages.append(buf);
1706 pages.extend_from_slice(b"b");
1707 assert_eq!(pages.num_pages(), 1);
1708 assert_eq!(pages.freeze(), "ab");
1709
1710 let mut buf = BytesMut::with_capacity(64);
1712 let cap = buf.capacity();
1713 buf.resize(cap, b'x');
1714 pages.append(buf);
1715 let page = BytePage::from(BytesMut::copy_from_slice([b'y'; 64]));
1716 let shared = page.clone();
1717 pages.append(page);
1718 pages.extend_from_slice(b"z");
1719 assert_eq!(pages.num_pages(), 3);
1720 assert_eq!(pages.len(), cap + 65);
1721 assert_eq!(shared, &[b'y'; 64][..]);
1722 }
1723
1724 fn mixed_pages() -> BytePages {
1726 let mut pages = BytePages::new(BytePageSize::Size4);
1727 pages.extend_from_slice(b"current");
1728 pages.prepend(Bytes::copy_from_slice(&[b'b'; 64]));
1729 pages.prepend(Bytes::copy_from_slice(b"ab"));
1730 assert!(pages.pages()[0].is_inline());
1731 pages
1732 }
1733
1734 #[test]
1735 fn iter_pages() {
1736 let pages = BytePages::default();
1737 assert_eq!(pages.iter().count(), 0);
1738
1739 let pages = mixed_pages();
1740 let chunks: Vec<&[u8]> = pages.iter().collect();
1741 assert_eq!(chunks, [&b"ab"[..], &[b'b'; 64][..], &b"current"[..]]);
1742 assert_eq!(chunks.len(), pages.num_pages());
1743
1744 let ptrs: Vec<*const u8> = pages.iter().map(<[u8]>::as_ptr).collect();
1746 let moved = Box::new(pages);
1747 let moved_ptrs: Vec<*const u8> = moved.iter().map(<[u8]>::as_ptr).collect();
1748 assert_eq!(ptrs, moved_ptrs);
1749
1750 let mut pages = BytePages::new(BytePageSize::Size4);
1752 pages.extend_from_slice(b"data");
1753 pages.prepend(Bytes::copy_from_slice(b"ab"));
1754 pages.advance_to(6);
1755 assert_eq!(pages.iter().count(), 0);
1756 assert_eq!(pages.num_pages(), 0);
1757 }
1758
1759 #[test]
1760 fn advance_to_pages() {
1761 let mut pages = mixed_pages();
1762 let len = pages.len();
1763 pages.advance_to(0);
1764 assert_eq!(pages.len(), len);
1765
1766 pages.advance_to(2);
1768 assert_eq!(pages.len(), len - 2);
1769 assert_eq!(pages.num_pages(), 2);
1770 assert_eq!(pages.iter().next().unwrap(), &[b'b'; 64][..]);
1771
1772 pages.advance_to(60);
1774 assert_eq!(pages.len(), 11);
1775 assert_eq!(pages.num_pages(), 2);
1776 let chunks: Vec<&[u8]> = pages.iter().collect();
1777 assert_eq!(chunks, [&b"bbbb"[..], &b"current"[..]]);
1778
1779 pages.advance_to(6);
1781 assert_eq!(pages.len(), 5);
1782 assert_eq!(pages.num_pages(), 1);
1783 assert_eq!(pages.iter().next().unwrap(), b"rrent");
1784
1785 let ptr = pages.iter().next().unwrap().as_ptr();
1787 pages.advance_to(5);
1788 assert!(pages.is_empty());
1789 assert_eq!(pages.num_pages(), 0);
1790 pages.extend_from_slice(b"next");
1791 assert_eq!(pages.num_pages(), 1);
1792 assert_eq!(pages.iter().next().unwrap().as_ptr(), ptr.wrapping_add(5));
1793 assert_eq!(pages.freeze(), "next");
1794 }
1795
1796 #[test]
1797 fn move_to_keeps_pages() {
1798 let mut src = mixed_pages();
1800 let ptrs: Vec<*const u8> = src
1801 .iter()
1802 .filter(|s| s.len() > 2)
1803 .map(<[u8]>::as_ptr)
1804 .collect();
1805 let mut dst = BytePages::new(BytePageSize::Size16);
1806 src.move_to(&mut dst);
1807 assert!(src.is_empty());
1808 assert_eq!(src.num_pages(), 0);
1809 assert_eq!(dst.page_size(), BytePageSize::Size16);
1810 assert_eq!(dst.num_pages(), 3);
1811 assert_eq!(dst.len(), 73);
1812 let moved: Vec<*const u8> = dst
1813 .iter()
1814 .filter(|s| s.len() > 2)
1815 .map(<[u8]>::as_ptr)
1816 .collect();
1817 assert_eq!(ptrs, moved);
1818
1819 let mut dst = BytePages::new(BytePageSize::Size4);
1822 dst.extend_from_slice(b"first");
1823 dst.prepend(Bytes::copy_from_slice(b"0"));
1824 let mut src = mixed_pages();
1825 src.move_to(&mut dst);
1826 let chunks: Vec<&[u8]> = dst.iter().collect();
1827 assert_eq!(
1828 chunks,
1829 [
1830 &b"0"[..],
1831 &b"first"[..],
1832 &b"ab"[..],
1833 &[b'b'; 64][..],
1834 &b"current"[..]
1835 ]
1836 );
1837 assert_eq!(dst.len(), 79);
1838 dst.extend_from_slice(b"last");
1839 assert_eq!(dst.num_pages(), 6);
1840
1841 let mut src = BytePages::default();
1843 src.move_to(&mut dst);
1844 assert_eq!(dst.num_pages(), 6);
1845 }
1846
1847 #[test]
1848 fn advance_to_vec_page() {
1849 let mut pages = BytePages::default();
1850 pages.prepend(b"hello world".to_vec());
1851 pages.advance_to(6);
1852 assert_eq!(pages.len(), 5);
1853 assert_eq!(pages.freeze(), "world");
1854 }
1855
1856 #[test]
1857 #[should_panic(expected = "cannot advance past the end of the buffer")]
1858 fn advance_to_past_end() {
1859 let mut pages = mixed_pages();
1860 pages.advance_to(pages.len() + 1);
1861 }
1862}