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: StorageVec,
10}
11
12struct Inner {
13 size: BytePageSize,
14 pages: VecDeque<BytePage>,
15}
16
17thread_local! {
18 static CACHE: Cell<Option<Box<Vec<Box<Inner>>>>> = Cell::new(Some(Box::default()));
19}
20const CACHE_SIZE: usize = 128;
21
22impl BytePages {
23 pub fn new(size: BytePageSize) -> Self {
28 debug_assert!(size != BytePageSize::Unset, "Page cannot be Unset");
29
30 let st = CACHE.with(move |c| {
31 let mut cache = c.take().unwrap();
32
33 let item = if let Some(mut item) = cache.pop() {
34 item.size = size;
35 item
36 } else {
37 Box::new(Inner {
38 size,
39 pages: VecDeque::with_capacity(8),
40 })
41 };
42 c.set(Some(cache));
43 item
44 });
45
46 BytePages {
47 st: Some(st),
48 current: StorageVec::sized(size),
49 }
50 }
51
52 fn pages(&self) -> &VecDeque<BytePage> {
53 &self.st.as_ref().unwrap().pages
54 }
55
56 fn pages_mut(&mut self) -> &mut VecDeque<BytePage> {
57 &mut self.st.as_mut().unwrap().pages
58 }
59
60 pub fn page_size(&self) -> BytePageSize {
62 self.st.as_ref().unwrap().size
63 }
64
65 pub fn set_page_size(&mut self, size: BytePageSize) {
67 self.st.as_mut().unwrap().size = size;
68 }
69
70 pub fn prepend<T>(&mut self, buf: T) -> bool
72 where
73 BytePage: From<T>,
74 {
75 let p = BytePage::from(buf);
76 if p.is_empty() {
77 false
78 } else {
79 self.pages_mut().push_front(p);
80 true
81 }
82 }
83
84 pub fn append<T>(&mut self, buf: T)
86 where
87 BytePage: From<T>,
88 {
89 let p = BytePage::from(buf);
90 let remaining = self.current.remaining();
91
92 if p.len() <= remaining {
93 self.put_slice(p.as_ref());
94 } else if self.current.len() == 0 {
95 match p.into_storage() {
96 Ok(st) => {
97 self.current = st;
98 }
99 Err(page) => {
100 self.pages_mut().push_back(page);
102 }
103 }
104 } else {
105 let storage = StorageVec::sized(self.page_size());
107 let page: BytePage = From::from(mem::replace(&mut self.current, storage));
108 let pages = self.pages_mut();
109 pages.push_back(page);
110 pages.push_back(p);
112 }
113 }
114
115 #[inline]
116 pub fn extend_from_slice(&mut self, extend: &[u8]) {
122 self.put_slice(extend);
123 }
124
125 #[inline]
126 pub fn len(&self) -> usize {
128 self.pages()
129 .iter()
130 .fold(self.current.len(), |c, page| c + page.len())
131 }
132
133 #[inline]
134 pub fn is_empty(&self) -> bool {
136 for p in self.pages() {
137 if !p.is_empty() {
138 return false;
139 }
140 }
141 self.current.len() == 0
142 }
143
144 #[inline]
145 pub fn num_pages(&self) -> usize {
147 if self.current.len() == 0 {
148 self.pages().len()
149 } else {
150 self.pages().len() + 1
151 }
152 }
153
154 pub fn take(&mut self) -> Option<BytePage> {
156 if let Some(page) = self.pages_mut().pop_front() {
157 Some(page)
158 } else if self.current.len() == 0 {
159 None
160 } else {
161 let storage = StorageVec::sized(self.page_size());
162 Some(BytePage::from(mem::replace(&mut self.current, storage)))
163 }
164 }
165
166 #[inline]
167 pub fn copy_to(&self, pages: &mut BytePages) {
172 for p in self.pages() {
173 pages.append(p.clone());
174 }
175
176 if self.current.len() != 0 {
177 pages.append(BytePage::from(Bytes::copy_from_slice(
178 self.current.as_ref(),
179 )));
180 }
181 }
182
183 #[inline]
184 pub fn move_to(&mut self, pages: &mut BytePages) {
186 while let Some(page) = self.take() {
187 pages.append(page);
188 }
189 }
190
191 #[must_use]
199 pub fn split_to(&mut self, at: usize) -> BytePages {
200 let mut pages = BytePages::new(self.page_size());
201 self.split_into(at, &mut pages);
202 pages
203 }
204
205 pub fn split_into(&mut self, mut at: usize, to: &mut BytePages) {
213 {
214 let pages = self.pages_mut();
215
216 while let Some(mut page) = pages.pop_front() {
217 let len = cmp::min(page.len(), at);
218 to.append(page.split_to(len));
219
220 if !page.is_empty() {
221 pages.push_front(page);
222 return;
223 }
224 at -= len;
225 }
226 }
227 if at > 0
228 && let Some(mut page) = self.take()
229 {
230 let len = cmp::min(page.len(), at);
231 to.append(page.split_to(len));
232 self.append(page);
233 }
234 }
235
236 #[inline]
238 #[must_use]
239 pub fn freeze(&mut self) -> Bytes {
240 let pages = self.num_pages();
241 if pages == 0 || self.is_empty() {
242 Bytes::new()
243 } else if pages == 1 {
244 self.take().unwrap().freeze()
245 } else {
246 let mut buf = BytesMut::with_capacity(self.len());
247 while let Some(p) = self.take() {
248 buf.extend_from_slice(&p);
249 }
250 buf.freeze()
251 }
252 }
253
254 #[inline]
255 pub fn try_get_current_from(&mut self, pages: &mut BytePages) {
256 if self.pages().is_empty() && self.current.len() == 0 && pages.current.len() != 0 {
257 self.current =
258 mem::replace(&mut pages.current, StorageVec::sized(self.page_size()));
259 }
260 }
261
262 pub fn with_bytes_mut<F, R>(&mut self, f: F) -> R
264 where
265 F: FnOnce(&mut BytesMut) -> R,
266 {
267 let mut buf = BytesMut {
268 storage: StorageVec(self.current.0),
269 };
270 buf.storage.unsize();
271
272 let res = f(&mut buf);
273 mem::forget(buf);
274 res
275 }
276}
277
278impl Drop for BytePages {
279 fn drop(&mut self) {
280 CACHE.with(move |c| {
281 let mut cache = c.take().unwrap();
282 if cache.len() < CACHE_SIZE {
283 let mut st = self.st.take().unwrap();
284 st.pages.clear();
285 cache.push(st);
286 }
287 c.set(Some(cache));
288 });
289 }
290}
291
292impl fmt::Debug for BytePages {
293 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
294 let mut f = fmt.debug_tuple("BytePages");
295 for p in self.pages() {
296 f.field(p);
297 }
298 if self.current.len() != 0 {
299 f.field(&crate::debug::BsDebug(self.current.as_ref()));
300 }
301 f.finish()
302 }
303}
304
305impl Default for BytePages {
306 fn default() -> Self {
307 BytePages::new(BytePageSize::Size16)
308 }
309}
310
311impl BufMut for BytePages {
312 #[inline]
313 fn remaining_mut(&self) -> usize {
314 self.current.remaining()
315 }
316
317 #[inline]
318 unsafe fn advance_mut(&mut self, cnt: usize) {
319 self.current.set_len(self.current.len() + cnt);
321 }
322
323 #[inline]
324 fn chunk_mut(&mut self) -> &mut UninitSlice {
325 unsafe {
326 let ptr = &mut self.current.as_ptr();
328 UninitSlice::from_raw_parts_mut(
329 ptr.add(self.current.len()),
330 self.remaining_mut(),
331 )
332 }
333 }
334
335 fn put_slice(&mut self, mut src: &[u8]) {
336 while !src.is_empty() {
337 let amount = cmp::min(src.len(), self.current.remaining());
338 unsafe {
339 ptr::copy_nonoverlapping(
340 src.as_ptr(),
341 self.chunk_mut().as_mut_ptr(),
342 amount,
343 );
344 self.advance_mut(amount);
345 }
346 src = &src[amount..];
347
348 if self.current.is_full() {
350 let storage = StorageVec::sized(self.page_size());
351 let page = BytePage::from(mem::replace(&mut self.current, storage));
352 self.pages_mut().push_back(page);
353 }
354 }
355 }
356
357 #[inline]
358 fn put_u8(&mut self, n: u8) {
359 self.current.put_u8(n);
360 if self.current.is_full() {
361 let storage = StorageVec::sized(self.page_size());
362 let page: BytePage = From::from(mem::replace(&mut self.current, storage));
363 self.pages_mut().push_back(page);
364 }
365 }
366
367 #[inline]
368 fn put_i8(&mut self, n: i8) {
369 self.put_u8(n as u8);
370 }
371}
372
373impl Clone for BytePages {
374 fn clone(&self) -> Self {
375 let size = self.page_size();
376 let mut pages = BytePages::new(size);
377 self.copy_to(&mut pages);
378 pages
379 }
380}
381
382impl io::Write for BytePages {
383 fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
384 self.put_slice(src);
385 Ok(src.len())
386 }
387
388 fn flush(&mut self) -> Result<(), io::Error> {
389 Ok(())
390 }
391}
392
393impl From<BytePages> for Bytes {
394 fn from(pages: BytePages) -> Bytes {
395 BytesMut::from(pages).freeze()
396 }
397}
398
399impl From<BytePages> for BytesMut {
400 fn from(mut pages: BytePages) -> BytesMut {
401 let mut buf = BytesMut::with_capacity(pages.len());
402 while let Some(p) = pages.take() {
403 buf.extend_from_slice(&p);
404 }
405 buf
406 }
407}
408
409pub struct BytePage {
410 inner: StorageType,
411}
412
413enum StorageType {
414 Bytes(Bytes),
415 Storage(StorageVec),
416 Vec(Vec<u8>),
417}
418
419impl BytePage {
420 #[inline]
421 pub fn len(&self) -> usize {
423 match &self.inner {
424 StorageType::Bytes(b) => b.len(),
425 StorageType::Storage(b) => b.len(),
426 StorageType::Vec(b) => b.len(),
427 }
428 }
429
430 #[inline]
431 pub fn is_empty(&self) -> bool {
433 match &self.inner {
434 StorageType::Bytes(b) => b.is_empty(),
435 StorageType::Storage(b) => b.len() == 0,
436 StorageType::Vec(b) => b.is_empty(),
437 }
438 }
439
440 pub fn as_ptr(&self) -> *const u8 {
442 unsafe {
443 match &self.inner {
444 StorageType::Bytes(b) => b.storage.as_ptr(),
445 StorageType::Storage(b) => b.as_ptr(),
446 StorageType::Vec(b) => b.as_ptr(),
447 }
448 }
449 }
450
451 #[must_use]
459 pub fn split_to(&mut self, at: usize) -> BytePage {
460 match &mut self.inner {
461 StorageType::Bytes(b) => {
462 let buf = b.split_to(cmp::min(at, b.len()));
463 BytePage {
464 inner: StorageType::Bytes(buf),
465 }
466 }
467 StorageType::Storage(_) => {
468 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
469 if let StorageType::Storage(st) = inner {
470 self.inner = StorageType::Bytes(Bytes {
471 storage: st.freeze(),
472 });
473 self.split_to(at)
474 } else {
475 unreachable!()
476 }
477 }
478 StorageType::Vec(_) => {
479 let inner = mem::replace(&mut self.inner, StorageType::Bytes(Bytes::new()));
480 if let StorageType::Vec(b) = inner {
481 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b));
482 self.split_to(at)
483 } else {
484 unreachable!()
485 }
486 }
487 }
488 }
489
490 #[inline]
499 pub fn advance_to(&mut self, cnt: usize) {
500 match &mut self.inner {
501 StorageType::Bytes(b) => b.advance_to(cnt),
502 StorageType::Storage(b) => unsafe { b.set_start(cnt as u32) },
503 StorageType::Vec(b) => {
504 self.inner = StorageType::Bytes(Bytes::copy_from_slice(&b[cnt..]));
505 }
506 }
507 }
508
509 #[inline]
511 #[must_use]
512 pub fn freeze(self) -> Bytes {
513 match self.inner {
514 StorageType::Bytes(b) => b,
515 StorageType::Storage(st) => Bytes {
516 storage: st.freeze(),
517 },
518 StorageType::Vec(v) => Bytes::from(v),
519 }
520 }
521
522 fn into_storage(self) -> Result<StorageVec, Self> {
523 if let StorageType::Storage(mut st) = self.inner {
524 if !st.is_full() && st.is_unique() {
526 Ok(st)
527 } else {
528 Err(Self {
529 inner: StorageType::Storage(st),
530 })
531 }
532 } else {
533 Err(self)
534 }
535 }
536}
537
538impl Clone for BytePage {
539 fn clone(&self) -> Self {
540 let inner = match &self.inner {
541 StorageType::Bytes(b) => StorageType::Bytes(b.clone()),
542 StorageType::Storage(st) => {
543 StorageType::Storage(unsafe { st.clone() })
546 }
547 StorageType::Vec(b) => StorageType::Bytes(Bytes::copy_from_slice(b)),
548 };
549
550 Self { inner }
551 }
552}
553
554impl AsRef<[u8]> for BytePage {
555 #[inline]
556 fn as_ref(&self) -> &[u8] {
557 match &self.inner {
558 StorageType::Bytes(b) => b.as_ref(),
559 StorageType::Storage(b) => b.as_ref(),
560 StorageType::Vec(b) => b.as_ref(),
561 }
562 }
563}
564
565impl Borrow<[u8]> for BytePage {
566 #[inline]
567 fn borrow(&self) -> &[u8] {
568 self.as_ref()
569 }
570}
571
572impl From<Bytes> for BytePage {
573 fn from(buf: Bytes) -> Self {
574 BytePage {
575 inner: StorageType::Bytes(buf),
576 }
577 }
578}
579
580impl<'a> From<&'a Bytes> for BytePage {
581 fn from(buf: &'a Bytes) -> Self {
582 BytePage {
583 inner: StorageType::Bytes(buf.clone()),
584 }
585 }
586}
587
588impl From<BytesMut> for BytePage {
589 fn from(buf: BytesMut) -> Self {
590 BytePage {
591 inner: StorageType::Storage(buf.storage),
592 }
593 }
594}
595
596impl From<ByteString> for BytePage {
597 fn from(s: ByteString) -> Self {
598 s.into_bytes().into()
599 }
600}
601
602impl<'a> From<&'a ByteString> for BytePage {
603 fn from(s: &'a ByteString) -> Self {
604 s.clone().into_bytes().into()
605 }
606}
607
608impl From<StorageVec> for BytePage {
609 fn from(buf: StorageVec) -> Self {
610 BytePage {
611 inner: StorageType::Storage(buf),
612 }
613 }
614}
615
616impl From<Vec<u8>> for BytePage {
617 fn from(buf: Vec<u8>) -> Self {
618 BytePage {
619 inner: StorageType::Vec(buf),
620 }
621 }
622}
623
624impl From<&'static str> for BytePage {
625 fn from(buf: &'static str) -> Self {
626 BytePage::from(Bytes::from_static(buf.as_bytes()))
627 }
628}
629
630impl From<&'static [u8]> for BytePage {
631 fn from(buf: &'static [u8]) -> Self {
632 BytePage::from(Bytes::from_static(buf))
633 }
634}
635
636impl<const N: usize> From<&'static [u8; N]> for BytePage {
637 fn from(src: &'static [u8; N]) -> Self {
638 BytePage::from(Bytes::from_static(src))
639 }
640}
641
642impl From<BytePage> for Bytes {
643 fn from(page: BytePage) -> Self {
644 match page.inner {
645 StorageType::Bytes(b) => b,
646 StorageType::Storage(storage) => BytesMut { storage }.freeze(),
647 StorageType::Vec(v) => Bytes::copy_from_slice(&v),
648 }
649 }
650}
651
652impl From<BytePage> for BytesMut {
653 fn from(page: BytePage) -> Self {
654 match page.inner {
655 StorageType::Bytes(b) => b.into(),
656 StorageType::Storage(storage) => BytesMut { storage },
657 StorageType::Vec(v) => BytesMut::copy_from_slice(&v),
658 }
659 }
660}
661
662impl PartialEq for BytePage {
663 fn eq(&self, other: &BytePage) -> bool {
664 self.as_ref() == other.as_ref()
665 }
666}
667
668impl<'a> PartialEq<&'a [u8]> for BytePage {
669 fn eq(&self, other: &&'a [u8]) -> bool {
670 self.as_ref() == *other
671 }
672}
673
674impl<'a, const N: usize> PartialEq<&'a [u8; N]> for BytePage {
675 fn eq(&self, other: &&'a [u8; N]) -> bool {
676 self.as_ref() == other.as_ref()
677 }
678}
679
680impl io::Read for BytePage {
681 fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
682 let len = cmp::min(self.len(), dst.len());
683 if len > 0 {
684 dst[..len].copy_from_slice(&self[..len]);
685 self.advance_to(len);
686 }
687 Ok(len)
688 }
689}
690
691impl ops::Deref for BytePage {
692 type Target = [u8];
693
694 #[inline]
695 fn deref(&self) -> &[u8] {
696 self.as_ref()
697 }
698}
699
700impl fmt::Debug for BytePage {
701 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
702 fmt::Debug::fmt(&crate::debug::BsDebug(self.as_ref()), fmt)
703 }
704}
705
706#[cfg(test)]
707mod tests {
708 use super::*;
709
710 #[test]
711 fn pages() {
712 let mut pages = BytePages::new(BytePageSize::Size8);
714 assert!(pages.is_empty());
715 assert_eq!(pages.len(), 0);
716 assert_eq!(pages.num_pages(), 0);
717 pages.extend_from_slice(b"b");
718 assert_eq!(pages.len(), 1);
719 assert_eq!(pages.num_pages(), 1);
720 pages.extend_from_slice("a".repeat(9 * 1024).as_bytes());
721 assert_eq!(pages.len(), 9217);
722 assert_eq!(pages.num_pages(), 2);
723 assert!(!pages.is_empty());
724
725 let mut pgs = BytePages::new(BytePageSize::Size8);
726 pgs.put_i8(b'a' as i8);
727 let p = pgs.take().unwrap();
728 assert_eq!(p.len(), 1);
729 assert_eq!(p.as_ref(), b"a");
730
731 pgs.extend_from_slice("a".repeat(8 * 1024 - 1).as_bytes());
732 assert_eq!(pgs.num_pages(), 1);
733 pgs.put_u8(b'a');
734 assert_eq!(pgs.num_pages(), 1);
735 assert_eq!(pgs.current.len(), 0);
736
737 pgs.put_u8(b'a');
738 assert_eq!(pgs.num_pages(), 2);
739
740 pgs.append(Bytes::copy_from_slice("a".repeat(8 * 1024).as_bytes()));
741 assert_eq!(pgs.num_pages(), 3);
742 assert_eq!(pgs.current.len(), 0);
743
744 let p = pages.take().unwrap();
746 assert_eq!(p.len(), 8192);
747 let p = pages.take().unwrap();
748 assert_eq!(p.len(), 1025);
749 assert!(!p.is_empty());
750 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
751 assert_eq!(p.as_ref(), "a".repeat(1025).as_bytes());
752 assert!(pages.take().is_none());
753
754 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
755 assert_eq!(p.len(), 3);
756 assert!(!p.is_empty());
757 assert_eq!(p.as_ref(), b"123");
758 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
759
760 let p = BytePage::from(&b"123"[..]);
761 assert_eq!(p.len(), 3);
762 assert!(!p.is_empty());
763 assert_eq!(p.as_ref(), b"123");
764 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
765
766 let p = BytePage::from(b"123");
767 assert_eq!(p.len(), 3);
768 assert!(!p.is_empty());
769 assert_eq!(p.as_ref(), b"123");
770 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
771
772 let p = BytePage::from("123");
773 assert_eq!(p.len(), 3);
774 assert!(!p.is_empty());
775 assert_eq!(p.as_ref(), b"123");
776 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
777 assert_eq!(p.freeze(), b"123");
778
779 let p = BytePage::from(vec![b'1', b'2', b'3']);
780 assert_eq!(p.len(), 3);
781 assert!(!p.is_empty());
782 assert_eq!(p.as_ref(), b"123");
783 assert_eq!(p.as_ref().as_ptr(), p.as_ptr());
784 assert_eq!(p.freeze(), b"123");
785
786 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
787 p.advance_to(1);
788 assert_eq!(p.len(), 2);
789 assert!(!p.is_empty());
790 assert_eq!(p.as_ref(), b"23");
791
792 let mut pages = BytePages::new(BytePageSize::Size8);
794 pages.extend_from_slice(b"b");
795 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\")");
796 let p = pages.take().unwrap();
797 assert_eq!(p.as_ref(), b"b");
798
799 let mut pages = BytePages::new(BytePageSize::Size8);
800 pages.extend_from_slice(b"a");
801 pages.append(Bytes::copy_from_slice(b"123"));
802 pages.pages_mut().push_back(p);
803 assert_eq!(format!("{pages:?}"), "BytePages(b\"b\", b\"a123\")");
804 }
805
806 #[test]
807 fn pages_copy_to() {
808 let mut pages = BytePages::default();
809 let mut pages2 = BytePages::default();
810 pages.put_slice(b"456");
811 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
812 pages.copy_to(&mut pages2);
813 let p = pages.freeze();
814 assert_eq!(p, b"123456");
815 let p2 = pages2.freeze();
816 assert_eq!(p2, b"123456");
817
818 let mut pages = BytePages::default();
819 let mut pages2 = BytePages::default();
820 pages.put_slice(b"456");
821 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
822 pages.copy_to(&mut pages2);
823 pages.put_u8(b'7');
824 let p = pages.freeze();
825 assert_eq!(p, b"1234567");
826 let p2 = pages2.freeze();
827 assert_eq!(p2, b"123456");
828
829 let mut pages = BytePages::default();
830 pages.put_slice(b"456");
831 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
832 let mut pages2 = pages.clone();
833 pages.put_u8(b'7');
834 let p = pages.freeze();
835 assert_eq!(p, b"1234567");
836 let p2 = pages2.freeze();
837 assert_eq!(p2, b"123456");
838 }
839
840 #[test]
841 fn pages_methods() {
842 let mut pages = BytePages::default();
844 pages.put_slice(b"456");
845 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
846 let mut pages2 = pages.split_to(1);
847 let p = pages.freeze();
848 assert_eq!(p, b"23456");
849 let p2 = pages2.freeze();
850 assert_eq!(p2, b"1");
851
852 let mut pages = BytePages::default();
853 pages.put_slice(b"456");
854 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
855 let mut pages2 = pages.split_to(4);
856 let p = pages.freeze();
857 assert_eq!(p, b"56");
858 let p2 = pages2.freeze();
859 assert_eq!(p2, b"1234");
860
861 let mut pages = BytePages::default();
863 pages.put_slice(b"456");
864 pages.prepend(BytePage::from(Bytes::copy_from_slice(b"123")));
865 let mut pages2 = BytePages::default();
866 pages.split_into(1, &mut pages2);
867 let p = pages.freeze();
868 assert_eq!(p, b"23456");
869 let p2 = pages2.freeze();
870 assert_eq!(p2, b"1");
871
872 let mut pages = BytePages::default();
874 pages.with_bytes_mut(|buf| buf.extend_from_slice(b"123"));
875 let p = pages.freeze();
876 assert_eq!(p, b"123");
877 }
878
879 #[test]
880 fn page_clone() {
881 let p = BytePage::from(Bytes::copy_from_slice(b"123"));
883 let p2 = p.clone();
884 assert_eq!(p, p2);
885
886 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
888 if let StorageType::Storage(ref mut st) = p.inner {
889 assert!(st.is_unique());
890 } else {
891 panic!()
892 }
893 let p2 = p.clone();
894 assert_eq!(p, p2);
895 if let StorageType::Storage(mut st) = p.inner {
896 assert!(!st.is_unique());
897 } else {
898 panic!()
899 }
900
901 let p = BytePage::from(vec![b'1', b'2', b'3']);
903 let p2 = p.clone();
904 assert_eq!(p, p2);
905 if let StorageType::Bytes(_) = p2.inner {
906 } else {
907 panic!()
908 }
909 }
910
911 #[test]
912 fn page_split_to() {
913 let mut p = BytePage::from(Bytes::copy_from_slice(b"123"));
915 let p2 = p.split_to(1);
916 assert_eq!(p, b"23");
917 assert_eq!(p2, b"1");
918
919 let mut p = BytePage::from(BytesMut::copy_from_slice(b"123"));
921 let p2 = p.split_to(1);
922 assert_eq!(p, b"23");
923 assert_eq!(p2, b"1");
924
925 let mut p = BytePage::from(vec![b'1', b'2', b'3']);
927 let p2 = p.split_to(1);
928 assert_eq!(p, b"23");
929 assert_eq!(p2, b"1");
930 }
931
932 #[test]
933 fn page_read() {
934 use std::io::Read;
935
936 let mut page = BytePage::from(Bytes::copy_from_slice(b"123"));
937
938 let mut buf = [0; 10];
939 assert_eq!(page.read(&mut buf).unwrap(), 3);
940 assert_eq!(page.len(), 0);
941 assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
942 }
943}