irox_tools/read/
pagefile.rs1use irox_bits::{Error, SeekRead, SeekWrite};
6use std::fs::File;
7use std::path::Path;
8
9pub const FILE_FLAG_NO_BUFFERING: u32 = 0x20000000;
10pub const FILE_FLAG_RANDOM_ACCESS: u32 = 0x10000000;
11pub const FILE_FLAG_WRITE_THROUGH: u32 = 0x80000000;
12pub const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
13
14pub struct Pagefile {
15 backing_file: File,
16}
17
18impl Pagefile {
19 pub fn open<T: AsRef<Path>>(path: T) -> Result<Pagefile, Error> {
20 let backing_file = std::fs::OpenOptions::new()
21 .read(true)
22 .write(true)
23 .create(true)
24 .truncate(false)
25 .open(path)?;
31 Ok(Pagefile { backing_file })
32 }
33
34 pub fn read_page<const N: usize>(&mut self, page_num: u64) -> Result<[u8; N], Error> {
35 let mut buf = [0; N];
36 let offset = page_num * N as u64;
37 let read = self.backing_file.seek_read(&mut buf, offset)?;
38 debug_assert!(
39 read == 0 || read == N,
40 "Read less than expected (0 < {read} < {N}) "
41 );
42 Ok(buf)
43 }
44 pub fn write_page<const N: usize>(
45 &mut self,
46 page_num: u64,
47 data: &[u8; N],
48 ) -> Result<(), Error> {
49 let offset = page_num * N as u64;
50 let write = self.backing_file.seek_write(data, offset)?;
51 debug_assert!(write == N, "Wrote less than expected ({write} != {N})");
52 Ok(())
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use crate::random::PRNG;
59 use crate::read::Pagefile;
60 use irox_bits::Error;
61 use std::io::Write;
62
63 #[test]
64 #[ignore]
65 pub fn test() -> Result<(), Error> {
66 let mut file = Pagefile::open("test_page.pagefile")?;
67 let mut rnd = crate::random::PcgXslRrRr::new_seed(0);
68
69 let mut page = [0u8; 4096];
70 let start = std::time::Instant::now();
71 for idx in 0..=1_000_000 {
72 let mut sli = page.as_mut_slice();
73 for _i in 0..32 {
74 sli.write_all(&rnd.next_u128().to_be_bytes())?;
75 }
76 file.write_page(idx, &page)?;
77 }
78 file.backing_file.sync_data()?;
79 let elapsed = start.elapsed();
80 let len = page.len() * 1_000_000;
81 let dur = elapsed.as_secs_f64();
82 println!(
83 "Wrote {} in {}s = {} MB/s",
84 len,
85 dur,
86 len as f64 / dur / 1e6
87 );
88 Ok(())
89 }
90}