1#![allow(clippy::missing_panics_doc, clippy::box_collection)]
2use std::{borrow::Borrow, cell::Cell, cmp, collections::VecDeque, fmt, io, mem, ops, ptr};
3
4use crate::{BufMut, BytePageSize, ByteString, Bytes, BytesMut};
5use crate::{buf::UninitSlice, stvec::StorageVec};
6
7pub struct BytePages {
8 st: Option<Box<Inner>>,
9 current: Option<StorageVec>,
10}
11
12#[derive(Debug)]
13struct Inner {
14 size: BytePageSize,
15 pages: VecDeque<BytePage>,
16}
17
18thread_local! {
19 static CACHE: Cell<Option<Box<Vec<Box<Inner>>>>> = Cell::new(Some(Box::default()));
20}
21const CACHE_SIZE: usize = 128;
22
23impl BytePages {
24 pub fn new(size: BytePageSize) -> Self {
29 debug_assert!(size != BytePageSize::Unset, "Page cannot be Unset");
30
31 let st = CACHE.with(move |c| {
32 let mut cache = c.take().unwrap();
33
34 let item = if let Some(mut item) = cache.pop() {
35 item.size = size;
36 item
37 } else {
38 Box::new(Inner {
39 size,
40 pages: VecDeque::with_capacity(8),
41 })
42 };
43 c.set(Some(cache));
44 item
45 });
46
47 BytePages {
48 st: Some(st),
49 current: None,
50 }
51 }
52
53 fn pages(&self) -> &VecDeque<BytePage> {
54 &self.st.as_ref().unwrap().pages
55 }
56
57 fn pages_mut(&mut self) -> &mut VecDeque<BytePage> {
58 &mut self.st.as_mut().unwrap().pages
59 }
60
61 fn push_back(&mut self, page: BytePage) {
62 let pages = &mut self.st.as_mut().unwrap().pages;
63 pages.push_back(page);
64
65 #[cfg(feature = "overuse")]
66 if pages.len() == 128 {
67 log::debug!(
68 "Number of pages {}\n{:?}",
69 pages.len(),
70 backtrace::Backtrace::new()
71 );
72 }
73 }
74
75 pub fn page_size(&self) -> BytePageSize {
77 self.st.as_ref().unwrap().size
78 }
79
80 pub fn set_page_size(&mut self, size: BytePageSize) {
82 self.st.as_mut().unwrap().size = size;
83 }
84
85 pub fn prepend<T>(&mut self, buf: T) -> bool
87 where
88 BytePage: From<T>,
89 {
90 let p = BytePage::from(buf);
91 if p.is_empty() {
92 false
93 } else {
94 self.pages_mut().push_front(p);
95 true
96 }
97 }
98
99 pub fn append<T>(&mut self, buf: T)
101 where
102 BytePage: From<T>,
103 {
104 let p = BytePage::from(buf);
105 if !p.is_empty() {
106 if self.current_len() == 0 {
107 match p.into_storage() {
108 Ok(st) => {
109 self.current = Some(st);
110 }
111 Err(page) => {
112 self.push_back(page);
114 }
115 }
116 } else if p.len() <= self.remaining_mut() {
117 self.put_slice(p.as_ref());
118 } else {
119 let page = self.current.take();
120 let pages = self.pages_mut();
121
122 if let Some(page) = page {
124 pages.push_back(From::from(page));
125 }
126 pages.push_back(p);
128
129 #[cfg(feature = "overuse")]
130 if pages.len() == 128 {
131 log::debug!(
132 "Number of pages {}\n{:?}",
133 pages.len(),
134 backtrace::Backtrace::new()
135 );
136 }
137 }
138 }
139 }
140
141 #[inline]
142 pub fn extend_from_slice(&mut self, extend: &[u8]) {
148 self.put_slice(extend);
149 }
150
151 #[inline]
152 pub fn len(&self) -> usize {
154 self.pages()
155 .iter()
156 .fold(self.current_len(), |c, page| c + page.len())
157 }
158
159 fn current_len(&self) -> usize {
160 self.current
161 .as_ref()
162 .map(StorageVec::len)
163 .unwrap_or_default()
164 }
165
166 #[inline]
167 pub fn is_empty(&self) -> bool {
169 for p in self.pages() {
170 if !p.is_empty() {
171 return false;
172 }
173 }
174 self.current_len() == 0
175 }
176
177 #[inline]
178 pub fn num_pages(&self) -> usize {
180 if self.current.is_none() {
181 self.pages().len()
182 } else {
183 self.pages().len() + 1
184 }
185 }
186
187 pub fn take(&mut self) -> Option<BytePage> {
189 if let Some(page) = self.pages_mut().pop_front() {
190 Some(page)
191 } else {
192 self.current.take().map(BytePage::from)
193 }
194 }
195
196 #[inline]
197 pub fn copy_to(&self, pages: &mut BytePages) {
202 for p in self.pages() {
203 pages.append(p.clone());
204 }
205
206 if let Some(st) = &self.current {
207 pages.append(BytePage::from(Bytes::copy_from_slice(st.as_ref())));
208 }
209 }
210
211 #[inline]
212 pub fn move_to(&mut self, pages: &mut BytePages) {
214 while let Some(page) = self.take() {
215 pages.append(page);
216 }
217 }
218
219 #[must_use]
227 pub fn split_to(&mut self, at: usize) -> BytePages {
228 let mut pages = BytePages::new(self.page_size());
229 self.split_into(at, &mut pages);
230 pages
231 }
232
233 pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
241 {
242 let pages = self.pages_mut();
243
244 while let Some(mut page) = pages.pop_front() {
245 let len = cmp::min(page.len(), at);
246 to.append(page.split_to(len));
247
248 if !page.is_empty() {
249 pages.push_front(page);
250 return;
251 }
252 at -= len;
253 }
254 }
255 if at > 0
256 && let Some(mut page) = self.take()
257 {
258 let len = cmp::min(page.len(), at);
259 to.append(page.split_to(len));
260 self.append(page);
261 }
262 }
263
264 #[inline]
266 pub fn clear(&mut self) {
267 while self.take().is_some() {}
268 }
269
270 #[inline]
272 #[must_use]
273 pub fn freeze(&mut self) -> Bytes {
274 let pages = self.num_pages();
275 if pages == 0 || self.is_empty() {
276 Bytes::new()
277 } else if pages == 1 {
278 self.take().unwrap().freeze()
279 } else {
280 let mut buf = BytesMut::with_capacity(self.len());
281 while let Some(p) = self.take() {
282 buf.extend_from_slice(&p);
283 }
284 buf.freeze()
285 }
286 }
287
288 #[inline]
289 pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
290 if self.pages().is_empty()
291 && self.current.is_none()
292 && let Some(st) = pages.current.take()
293 {
294 self.current = Some(st);
295 }
296 }
297
298 pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
300 where
301 F: FnOnce(&mut BytesMut) -> R,
302 {
303 let mut st = self
304 .current
305 .take()
306 .unwrap_or_else(|| StorageVec::sized(self.page_size()));
307
308 let cap = st.capacity();
309 let mut buf = BytesMut {
310 storage: StorageVec(st.0),
311 };
312
313 let res = f(&mut buf);
314
315 st.0 = buf.storage.0;
317 if buf.capacity() != cap {
318 buf.storage.unsize();
319 }
320 mem::forget(buf);
322
323 if st.len() >= self.page_size().capacity() {
325 self.push_back(BytePage::from(st));
326 } else {
327 self.current = Some(st);
328 }
329
330 res
331 }
332
333 fn with_current<F, R>(&mut self, f: F) -> R
334 where
335 F: FnOnce(&mut StorageVec) -> R,
336 {
337 let mut st = self
338 .current
339 .take()
340 .unwrap_or_else(|| StorageVec::sized(self.page_size()));
341 let result = f(&mut st);
342
343 if st.is_full() {
345 self.push_back(BytePage::from(st));
346 } else {
347 self.current = Some(st);
348 }
349
350 result
351 }
352}
353
354impl Drop for BytePages {
355 fn drop(&mut self) {
356 CACHE.with(move |c| {
357 let mut cache = c.take().unwrap();
358 if cache.len() < CACHE_SIZE {
359 let mut st = self.st.take().unwrap();
360 st.pages.clear();
361 cache.push(st);
362 }
363 c.set(Some(cache));
364 });
365 }
366}
367
368impl fmt::Debug for BytePages {
369 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
370 let mut f = fmt.debug_tuple("BytePages");
371 for p in self.pages() {
372 f.field(p);
373 }
374 if let Some(st) = &self.current {
375 f.field(&crate::debug::BsDebug(st.as_ref()));
376 }
377 f.finish()
378 }
379}
380
381impl Default for BytePages {
382 fn default() -> Self {
383 BytePages::new(BytePageSize::Size16)
384 }
385}
386
387impl BufMut for BytePages {
388 #[inline]
389 fn remaining_mut(&self) -> usize {
390 self.current
391 .as_ref()
392 .map(StorageVec::remaining)
393 .unwrap_or_default()
394 }
395
396 #[inline]
397 unsafe fn advance_mut(&mut self, cnt: usize) {
398 let st = self.current.as_mut().unwrap();
400 st.set_len(st.len() + cnt);
401 }
402
403 #[inline]
404 fn chunk_mut(&mut self) -> &mut UninitSlice {
405 unsafe {
406 if self.current.is_none() {
407 self.current = Some(StorageVec::sized(self.page_size()));
408 }
409 let st = self.current.as_ref().unwrap();
411 let ptr = &mut st.as_ptr();
412 UninitSlice::from_raw_parts_mut(ptr.add(st.len()), self.remaining_mut())
413 }
414 }
415
416 fn put_slice(&mut self, mut src: &[u8]) {
417 while !src.is_empty() {
418 let amount = self.with_current(|st| {
419 let amount = cmp::min(src.len(), st.remaining());
420 unsafe {
421 let ptr = &mut st.as_ptr();
422 let chunk =
423 UninitSlice::from_raw_parts_mut(ptr.add(st.len()), st.remaining());
424
425 ptr::copy_nonoverlapping(src.as_ptr(), chunk.as_mut_ptr(), amount);
426 st.set_len(st.len() + amount);
427 }
428 amount
429 });
430
431 src = &src[amount..];
432 }
433 }
434
435 #[inline]
436 fn put_u8(&mut self, n: u8) {
437 self.with_current(|st| st.put_u8(n));
438 }
439
440 #[inline]
441 fn put_i8(&mut self, n: i8) {
442 self.put_u8(n as u8);
443 }
444}
445
446impl Clone for BytePages {
447 fn clone(&self) -> Self {
448 let size = self.page_size();
449 let mut pages = BytePages::new(size);
450 self.copy_to(&mut pages);
451 pages
452 }
453}
454
455impl io::Write for BytePages {
456 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
457 self.put_slice(src);
458 Ok(src.len())
459 }
460
461 fn flush(&mut self) -> Result<(), io::Error> {
462 Ok(())
463 }
464}
465
466impl From<BytePages> for Bytes {
467 fn from(pages: BytePages) -> Bytes {
468 BytesMut::from(pages).freeze()
469 }
470}
471
472impl From<BytePages> for BytesMut {
473 fn from(mut pages: BytePages) -> BytesMut {
474 let mut buf = BytesMut::with_capacity(pages.len());
475 while let Some(p) = pages.take() {
476 buf.extend_from_slice(&p);
477 }
478 buf
479 }
480}
481
482pub struct BytePage {
483 inner: StorageType,
484}
485
486enum StorageType {
487 Bytes(Bytes),
488 Storage(StorageVec),
489 Vec(Vec<u8>),
490}
491
492impl BytePage {
493 #[inline]
494 pub fn len(&self) -> usize {
496 match &self.inner {
497 StorageType::Bytes(b) => b.len(),
498 StorageType::Storage(b) => b.len(),
499 StorageType::Vec(b) => b.len(),
500 }
501 }
502
503 #[inline]
504 pub fn is_empty(&self) -> bool {
506 match &self.inner {
507 StorageType::Bytes(b) => b.is_empty(),
508 StorageType::Storage(b) => b.len() == 0,
509 StorageType::Vec(b) => b.is_empty(),
510 }
511 }
512
513 #[inline]
514 pub unsafe fn as_ptr(&self) -> *const u8 {
523 unsafe {
524 match &self.inner {
525 StorageType::Bytes(b) => b.storage.as_ptr(),
526 StorageType::Storage(b) => b.as_ptr(),
527 StorageType::Vec(b) => b.as_ptr(),
528 }
529 }
530 }
531
532 #[must_use]
540 pub fn split_to(&mut self, at: usize) -> BytePage {
541 match &mut self.inner {
542 StorageType::Bytes(b) => {
543 let buf = b.split_to(cmp::min(at, b.len()));
544 BytePage {
545 inner: StorageType::Bytes(buf),
546 }
547 }
548 StorageType::Storage(_) => {
549 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
550 if let StorageType::Storage(st) = inner {
551 self.inner = StorageType::Bytes(Bytes {
552 storage: st.freeze(),
553 });
554 self.split_to(at)
555 } else {
556 unreachable!()
557 }
558 }
559 StorageType::Vec(_) => {
560 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
561 if let StorageType::Vec(b) = inner {
562 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
563 self.split_to(at)
564 } else {
565 unreachable!()
566 }
567 }
568 }
569 }
570
571 #[inline]
580 pub fn advance_to(&mut self, cnt: usize) {
581 match &mut self.inner {
582 StorageType::Bytes(b) => b.advance_to(cnt),
583 StorageType::Storage(b) => unsafe { b.set_start(cnt as u32) },
584 StorageType::Vec(b) => {
585 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
586 }
587 }
588 }
589
590 #[inline]
592 #[must_use]
593 pub fn freeze(self) -> Bytes {
594 match self.inner {
595 StorageType::Bytes(b) => b,
596 StorageType::Storage(st) => Bytes {
597 storage: st.freeze(),
598 },
599 StorageType::Vec(v) => Bytes::from(v),
600 }
601 }
602
603 fn into_storage(self) -> Result<StorageVec, Self> {
604 if let StorageType::Storage(mut st) = self.inner {
605 if !st.is_full() && st.is_unique() {
607 Ok(st)
608 } else {
609 Err(Self {
610 inner: StorageType::Storage(st),
611 })
612 }
613 } else {
614 Err(self)
615 }
616 }
617}
618
619impl Clone for BytePage {
620 fn clone(&self) -> Self {
621 let inner = match &self.inner {
622 StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
623 StorageType::Storage(st) => {
624 StorageType::Storage(unsafe { st.clone() })
627 }
628 StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
629 };
630
631 Self { inner }
632 }
633}
634
635impl AsRef<[u8]> for BytePage {
636 #[inline]
637 fn as_ref(&self) -> &[u8] {
638 match &self.inner {
639 StorageType::Bytes(b) => b.as_ref(),
640 StorageType::Storage(b) => b.as_ref(),
641 StorageType::Vec(b) => b.as_ref(),
642 }
643 }
644}
645
646impl Borrow<[u8]> for BytePage {
647 #[inline]
648 fn borrow(&self) -> &[u8] {
649 self.as_ref()
650 }
651}
652
653impl From<Bytes> for BytePage {
654 fn from(buf: Bytes) -> Self {
655 BytePage {
656 inner: StorageType::Bytes(buf),
657 }
658 }
659}
660
661impl<'a> From<&'a Bytes> for BytePage {
662 fn from(buf: &'a Bytes) -> Self {
663 BytePage {
664 inner: StorageType::Bytes(buf.clone()),
665 }
666 }
667}
668
669impl From<BytesMut> for BytePage {
670 fn from(buf: BytesMut) -> Self {
671 BytePage {
672 inner: StorageType::Storage(buf.storage),
673 }
674 }
675}
676
677impl From<ByteString> for BytePage {
678 fn from(s: ByteString) -> Self {
679 s.into_bytes().into()
680 }
681}
682
683impl<'a> From<&'a ByteString> for BytePage {
684 fn from(s: &'a ByteString) -> Self {
685 s.clone().into_bytes().into()
686 }
687}
688
689impl From<StorageVec> for BytePage {
690 fn from(buf: StorageVec) -> Self {
691 BytePage {
692 inner: StorageType::Storage(buf),
693 }
694 }
695}
696
697impl From<Vec<u8>> for BytePage {
698 fn from(buf: Vec<u8>) -> Self {
699 BytePage {
700 inner: StorageType::Vec(buf),
701 }
702 }
703}
704
705impl From<&'static str> for BytePage {
706 fn from(buf: &'static str) -> Self {
707 BytePage::from(Bytes::from_static(buf.as_bytes()))
708 }
709}
710
711impl From<&'static [u8]> for BytePage {
712 fn from(buf: &'static [u8]) -> Self {
713 BytePage::from(Bytes::from_static(buf))
714 }
715}
716
717impl<const N: usize> From<&'static [u8; N]> for BytePage {
718 fn from(src: &'static [u8; N]) -> Self {
719 BytePage::from(Bytes::from_static(src))
720 }
721}
722
723impl From<BytePage> for Bytes {
724 fn from(page: BytePage) -> Self {
725 match page.inner {
726 StorageType::Bytes(b) => b,
727 StorageType::Storage(storage) => BytesMut { storage }.freeze(),
728 StorageType::Vec(v) => Bytes::copy_from_slice(&v),
729 }
730 }
731}
732
733impl From<BytePage> for BytesMut {
734 fn from(page: BytePage) -> Self {
735 match page.inner {
736 StorageType::Bytes(b) => b.into(),
737 StorageType::Storage(storage) => BytesMut { storage },
738 StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
739 }
740 }
741}
742
743impl PartialEq for BytePage {
744 fn eq(&self, other: &BytePage) -> bool {
745 self.as_ref() == other.as_ref()
746 }
747}
748
749impl<'a> PartialEq<&'a [u8]> for BytePage {
750 fn eq(&self, other: &&'a [u8]) -> bool {
751 self.as_ref() == *other
752 }
753}
754
755impl<'a, const N: usize> PartialEq<&'a [u8; N]> for BytePage {
756 fn eq(&self, other: &&'a [u8; N]) -> bool {
757 self.as_ref() == other.as_ref()
758 }
759}
760
761impl io::Read for BytePage {
762 fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
763 let len = cmp::min(self.len(), dst.len());
764 if len > 0 {
765 dst[..len].copy_from_slice(&self[..len]);
766 self.advance_to(len);
767 }
768 Ok(len)
769 }
770}
771
772impl ops::Deref for BytePage {
773 type Target = [u8];
774
775 #[inline]
776 fn deref(&self) -> &[u8] {
777 self.as_ref()
778 }
779}
780
781impl fmt::Debug for BytePage {
782 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
783 fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
784 }
785}
786
787#[cfg(test)]
788mod tests {
789 use rand::Rng;
790
791 use super::*;
792
793 #[test]
794 fn pages() {
795 unsafe {
796 let mut pages = BytePages::new(BytePageSize::Size8);
798 assert!(pages.is_empty());
799 assert_eq!(pages.len(), 0);
800 assert_eq!(pages.num_pages(), 0);
801 pages.extend_from_slice(b"b");
802 assert_eq!(pages.len(), 1);
803 assert_eq!(pages.num_pages(), 1);
804 pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
805 assert_eq!(pages.len(), 9217);
806 assert_eq!(pages.num_pages(), 2);
807 assert!(!pages.is_empty());
808
809 let mut pgs = BytePages::new(BytePageSize::Size8);
810 pgs.put_i8(b'a' as i8);
811 let p = pgs.take().unwrap();
812 assert_eq!(p.len(), 1);
813 assert_eq!(p.as_ref(), b"a");
814
815 pgs.extend_from_slice("a".repeat(8 * 1024 - 1).as_bytes());
816 assert_eq!(pgs.num_pages(), 1);
817 pgs.put_u8(b'a');
818 assert_eq!(pgs.num_pages(), 1);
819 assert!(pgs.current.is_none());
820
821 pgs.put_u8(b'a');
822 assert_eq!(pgs.num_pages(), 2);
823
824 pgs.append(Bytes::copy_from_slice("a".repeat(8 * 1024).as_bytes()));
825 assert_eq!(pgs.num_pages(), 3);
826 assert!(pgs.current.is_none());
827
828 let p = pages.take().unwrap();
830 assert_eq!(p.len(), 8192);
831 let p = pages.take().unwrap();
832 assert_eq!(p.len(), 1025);
833 assert!(!p.is_empty());
834 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
835 assert_eq!(p.as_ref(), "a".repeat(1025).as_bytes());
836 assert!(pages.take().is_none());
837
838 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
839 assert_eq!(p.len(), 3);
840 assert!(!p.is_empty());
841 assert_eq!(p.as_ref(), b"123");
842 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
843
844 let p = BytePage::from(&b"123"[..]);
845 assert_eq!(p.len(), 3);
846 assert!(!p.is_empty());
847 assert_eq!(p.as_ref(), b"123");
848 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
849
850 let p = BytePage::from(b"123");
851 assert_eq!(p.len(), 3);
852 assert!(!p.is_empty());
853 assert_eq!(p.as_ref(), b"123");
854 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
855
856 let p = BytePage::from("123");
857 assert_eq!(p.len(), 3);
858 assert!(!p.is_empty());
859 assert_eq!(p.as_ref(), b"123");
860 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
861 assert_eq!(p.freeze(), b"123");
862
863 let p = BytePage::from(vec![b'1', b'2', b'3']);
864 assert_eq!(p.len(), 3);
865 assert!(!p.is_empty());
866 assert_eq!(p.as_ref(), b"123");
867 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
868 assert_eq!(p.freeze(), b"123");
869
870 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
871 p.advance_to(1);
872 assert_eq!(p.len(), 2);
873 assert!(!p.is_empty());
874 assert_eq!(p.as_ref(), b"23");
875
876 let mut pages = BytePages::new(BytePageSize::Size8);
878 pages.extend_from_slice(b"b");
879 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
880 let p = pages.take().unwrap();
881 assert_eq!(p.as_ref(), b"b");
882
883 let mut pages = BytePages::new(BytePageSize::Size8);
884 pages.extend_from_slice(b"a");
885 pages.append(Bytes::copy_from_slice(b"123"));
886 pages.pages_mut().push_back(p);
887 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
888
889 assert_eq!(pages.len(), 5);
890 pages.clear();
891 assert_eq!(pages.len(), 0);
892 }
893 }
894
895 #[test]
896 fn pages_copy_to() {
897 let mut pages = BytePages::default();
898 let mut pages2 = BytePages::default();
899 pages.put_slice(b"456");
900 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
901 pages.copy_to(&mut pages2);
902 let p = pages.freeze();
903 assert_eq!(p, b"123456");
904 let p2 = pages2.freeze();
905 assert_eq!(p2, b"123456");
906
907 let mut pages = BytePages::default();
908 let mut pages2 = BytePages::default();
909 pages.put_slice(b"456");
910 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
911 pages.copy_to(&mut pages2);
912 pages.put_u8(b'7');
913 let p = pages.freeze();
914 assert_eq!(p, b"1234567");
915 let p2 = pages2.freeze();
916 assert_eq!(p2, b"123456");
917
918 let mut pages = BytePages::default();
919 pages.put_slice(b"456");
920 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
921 let mut pages2 = pages.clone();
922 pages.put_u8(b'7');
923 let p = pages.freeze();
924 assert_eq!(p, b"1234567");
925 let p2 = pages2.freeze();
926 assert_eq!(p2, b"123456");
927 }
928
929 #[test]
930 fn pages_methods() {
931 let mut pages = BytePages::default();
933 pages.put_slice(b"456");
934 pages.prepend(BytePage::from(&Bytes::copy_from_slice(b"123")));
935 let mut pages2 = pages.split_to(1);
936 let p = pages.freeze();
937 assert_eq!(p, b"23456");
938 let p2 = pages2.freeze();
939 assert_eq!(p2, b"1");
940
941 let mut pages = BytePages::default();
942 pages.put_slice(b"456");
943 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
944 let mut pages2 = pages.split_to(4);
945 let p = pages.freeze();
946 assert_eq!(p, b"56");
947 let p2 = pages2.freeze();
948 assert_eq!(p2, b"1234");
949
950 let mut pages = BytePages::default();
952 pages.put_slice(b"456");
953 pages.prepend(BytePage::from(crate::ByteString::from_static("123")));
954 let mut pages2 = BytePages::default();
955 pages.split_into(1, &mut pages2);
956 let p = pages.freeze();
957 assert_eq!(p, b"23456");
958 let p2 = pages2.freeze();
959 assert_eq!(p2, b"1");
960
961 let mut pages = BytePages::default();
963 pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
964 assert_eq!(pages.len(), 3);
965 let p = pages.freeze();
966 assert_eq!(p, b"123");
967
968 let data = rand::rng()
969 .sample_iter(&rand::distr::Alphanumeric)
970 .take(65_536)
971 .map(char::from)
972 .collect::<String>();
973
974 let mut pages = BytePages::default();
975 pages.with_bytes_mut(|buf| buf.extend_from_slice(data.as_bytes()));
976 assert_eq!(pages.len(), 65_536);
977 let p = pages.freeze();
978 assert_eq!(p, data.as_bytes());
979
980 let page = BytePage::from(Bytes::copy_from_slice(b"123"));
982 assert_eq!(page, b"123");
983 assert_eq!(<BytePage as Borrow<[u8]>>::borrow(&page), b"123");
984 let b = Bytes::from(page);
985 assert_eq!(b, b"123");
986 }
987
988 #[test]
989 fn page_clone() {
990 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
992 let p2 = p.clone();
993 assert_eq!(p, p2);
994
995 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
997 if let StorageType::Storage(ref mut st) = p.inner {
998 assert!(st.is_unique());
999 } else {
1000 panic!()
1001 }
1002 let p2 = p.clone();
1003 assert_eq!(p, p2);
1004 if let StorageType::Storage(mut st) = p.inner {
1005 assert!(!st.is_unique());
1006 } else {
1007 panic!()
1008 }
1009
1010 let p = BytePage::from(vec![b'1', b'2', b'3']);
1012 let p2 = p.clone();
1013 assert_eq!(p, p2);
1014 if let StorageType::Bytes(_) = p2.inner {
1015 } else {
1016 panic!()
1017 }
1018 }
1019
1020 #[test]
1021 fn page_split_to() {
1022 let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
1024 let p2 = p.split_to(1);
1025 assert_eq!(p, b"23");
1026 assert_eq!(p2, b"1");
1027
1028 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
1030 let p2 = p.split_to(1);
1031 assert_eq!(p, b"23");
1032 assert_eq!(p2, b"1");
1033
1034 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
1036 let p2 = p.split_to(1);
1037 assert_eq!(p, b"23");
1038 assert_eq!(p2, b"1");
1039 }
1040
1041 #[test]
1042 fn page_read() {
1043 use std::io::Read;
1044
1045 let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
1046
1047 let mut buf = [0; 10];
1048 assert_eq!(page.read(&mut buf).unwrap(), 3);
1049 assert_eq!(page.len(), 0);
1050 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1051 }
1052}