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