]> git.proxmox.com Git - proxmox-backup.git/blame - examples/test_chunk_size.rs
ui: datastore: fix sync/verify job removal prompt
[proxmox-backup.git] / examples / test_chunk_size.rs
CommitLineData
1604ec26
DM
1extern crate proxmox_backup;
2
3// also see https://www.johndcook.com/blog/standard_deviation/
4
f7d4e4b5 5use anyhow::{Error};
1604ec26
DM
6use std::io::{Read, Write};
7
8use proxmox_backup::backup::*;
9
10struct ChunkWriter {
11 chunker: Chunker,
12 last_chunk: usize,
13 chunk_offset: usize,
14
15 chunk_count: usize,
16
14691fc1
DM
17 m_old: f64,
18 m_new: f64,
19 s_old: f64,
20 s_new: f64,
1604ec26
DM
21}
22
23impl ChunkWriter {
24
25 fn new(chunk_size: usize) -> Self {
26 ChunkWriter {
27 chunker: Chunker::new(chunk_size),
28 last_chunk: 0,
29 chunk_offset: 0,
30 chunk_count: 0,
31
14691fc1
DM
32 m_old: 0.0,
33 m_new: 0.0,
34 s_old: 0.0,
35 s_new: 0.0,
1604ec26
DM
36 }
37 }
38
39 fn record_stat(&mut self, chunk_size: f64) {
40
41 self.chunk_count += 1;
42
43 if self.chunk_count == 1 {
14691fc1
DM
44 self.m_old = chunk_size;
45 self.m_new = chunk_size;
46 self.s_old = 0.0;
1604ec26 47 } else {
14691fc1
DM
48 self.m_new = self.m_old + (chunk_size - self.m_old)/(self.chunk_count as f64);
49 self.s_new = self.s_old +
50 (chunk_size - self.m_old)*(chunk_size - self.m_new);
1604ec26 51 // set up for next iteration
14691fc1
DM
52 self.m_old = self.m_new;
53 self.s_old = self.s_new;
1604ec26
DM
54 }
55
56 let variance = if self.chunk_count > 1 {
14691fc1 57 self.s_new/((self.chunk_count -1)as f64)
1604ec26
DM
58 } else { 0.0 };
59
60 let std_deviation = variance.sqrt();
14691fc1
DM
61 let deviation_per = (std_deviation*100.0)/self.m_new;
62 println!("COUNT {:10} SIZE {:10} MEAN {:10} DEVIATION {:3}%", self.chunk_count, chunk_size, self.m_new as usize, deviation_per as usize);
1604ec26
DM
63 }
64}
65
66impl Write for ChunkWriter {
67
68 fn write(&mut self, data: &[u8]) -> std::result::Result<usize, std::io::Error> {
69
70 let chunker = &mut self.chunker;
71
72 let pos = chunker.scan(data);
73
74 if pos > 0 {
75 self.chunk_offset += pos;
76
77 let chunk_size = self.chunk_offset - self.last_chunk;
78
79 self.record_stat(chunk_size as f64);
80
81 self.last_chunk = self.chunk_offset;
82 Ok(pos)
83
84 } else {
85 self.chunk_offset += data.len();
86 Ok(data.len())
87 }
88 }
89
90 fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
91 Ok(())
92 }
93}
94
95fn main() -> Result<(), Error> {
96
97 let mut file = std::fs::File::open("/dev/urandom")?;
98
99 let mut bytes = 0;
100
101 let mut buffer = [0u8; 64*1024];
102
103 let mut writer = ChunkWriter::new(4096*1024);
104
105 loop {
106
107 file.read_exact(&mut buffer)?;
108 bytes += buffer.len();
109
110 writer.write_all(&buffer)?;
111
14691fc1 112 if bytes > 1024*1024*1024 { break; }
1604ec26
DM
113 }
114
115 Ok(())
116}