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