1use std::fs::File;
2use std::io::{BufReader, Cursor, Read, Seek};
3
4use polars_buffer::Buffer;
5use polars_core::config::verbose;
6use polars_utils::mmap::MMapSemaphore;
7
8pub trait MmapBytesReader: Read + Seek + Send + Sync {
11 fn to_file(&self) -> Option<&File> {
12 None
13 }
14
15 fn to_bytes(&self) -> Option<&[u8]> {
16 None
17 }
18}
19
20impl MmapBytesReader for File {
21 fn to_file(&self) -> Option<&File> {
22 Some(self)
23 }
24}
25
26impl MmapBytesReader for BufReader<File> {
27 fn to_file(&self) -> Option<&File> {
28 Some(self.get_ref())
29 }
30}
31
32impl MmapBytesReader for BufReader<&File> {
33 fn to_file(&self) -> Option<&File> {
34 Some(self.get_ref())
35 }
36}
37
38impl<T> MmapBytesReader for Cursor<T>
39where
40 T: AsRef<[u8]> + Send + Sync,
41{
42 fn to_bytes(&self) -> Option<&[u8]> {
43 Some(self.get_ref().as_ref())
44 }
45}
46
47impl<T: MmapBytesReader + ?Sized> MmapBytesReader for Box<T> {
48 fn to_file(&self) -> Option<&File> {
49 T::to_file(self)
50 }
51
52 fn to_bytes(&self) -> Option<&[u8]> {
53 T::to_bytes(self)
54 }
55}
56
57impl<T: MmapBytesReader> MmapBytesReader for &mut T {
58 fn to_file(&self) -> Option<&File> {
59 T::to_file(self)
60 }
61
62 fn to_bytes(&self) -> Option<&[u8]> {
63 T::to_bytes(self)
64 }
65}
66
67pub enum ReaderBytes<'a> {
70 Borrowed(&'a [u8]),
71 Owned(Buffer<u8>),
72}
73
74impl std::ops::Deref for ReaderBytes<'_> {
75 type Target = [u8];
76 fn deref(&self) -> &[u8] {
77 match self {
78 Self::Borrowed(ref_bytes) => ref_bytes,
79 Self::Owned(vec) => vec,
80 }
81 }
82}
83
84impl<'a, T: 'a + MmapBytesReader> From<&'a mut T> for ReaderBytes<'a> {
85 fn from(m: &'a mut T) -> Self {
86 match m.to_bytes() {
87 Some(s) => {
89 let s = unsafe { std::mem::transmute::<&[u8], &'a [u8]>(s) };
90 ReaderBytes::Borrowed(s)
91 },
92 None => {
93 if let Some(f) = m.to_file() {
94 let mmap = MMapSemaphore::new_from_file(f).unwrap();
95 ReaderBytes::Owned(Buffer::from_owner(mmap))
96 } else {
97 if verbose() {
98 eprintln!("could not memory map file; read to buffer.")
99 }
100 let mut buf = vec![];
101 m.read_to_end(&mut buf).expect("could not read");
102 ReaderBytes::Owned(Buffer::from_vec(buf))
103 }
104 },
105 }
106 }
107}