Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_jdat/src/chunk.rs

3.8 KiB, 5 runs

created by r1870400018:457, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use crate::{
2 daticle::Dat,
3};
4
5use oxedyne_fe2o3_core::prelude::*;
6
7use rand_core::{
8 OsRng,
9 RngCore,
10};
11
12
13new_type!(PartKey, [u64; 5], Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd);
14
15impl PartKey {
16 pub fn set_id(&self) -> u64 { self.0[0] }
17 pub fn index(&self) -> u64 { self.0[1] }
18 pub fn data_len(&self) -> u64 { self.0[2] }
19 pub fn num_parts(&self) -> u64 { self.0[3] }
20 pub fn part_size(&self) -> u64 { self.0[4] }
21}
22
23#[derive(Clone, Debug, Default)]
24pub struct Chunker {
25 pub state: ChunkState,
26 pub cfg: ChunkConfig,
27}
28
29impl Chunker {
30
31 pub fn new(chunk_size: usize) -> Self {
32 Self {
33 cfg: ChunkConfig::default().set_size(chunk_size),
34 ..Default::default()
35 }
36 }
37
38 pub fn set_state(mut self, state: ChunkState) -> Self {
39 self.state = state;
40 self
41 }
42 pub fn set_config(mut self, cfg: ChunkConfig) -> Self {
43 self.cfg = cfg;
44 self
45 }
46 //pub fn state(&self) -> &ChunkState { &self.state }
47 //pub fn config(&self) -> &ChunkConfig { &self.cfg }
48
49
50 pub fn chunk(
51 &self,
52 vbuf: &[u8],
53 )
54 -> Outcome<(
55 Vec<Vec<u8>>, // The chunks (possibly Dat-wrapped).
56 ChunkState, // Info about the chunks.
57 )>
58 {
59 let data_len = vbuf.len();
60 let chunk_size = self.cfg.chunk_size;
61 let num_chunks = res!(oxedyne_fe2o3_num::int::usize_ceil_div(
62 data_len,
63 chunk_size,
64 ));
65 let chunk_state = ChunkState{
66 index: 0,
67 data_len,
68 num_chunks,
69 chunk_size,
70 };
71
72 let mut chunks = Vec::with_capacity(num_chunks);
73 for (i, chunk) in vbuf.chunks(chunk_size).enumerate() {
74 let mut cvbuf = chunk.to_vec();
75 if self.cfg.pad_last && (i == num_chunks - 1) && cvbuf.len() < chunk_size {
76 let mut padbuf = vec![0u8; chunk_size - cvbuf.len()];
77 OsRng.fill_bytes(&mut padbuf);
78 cvbuf.extend_from_slice(&padbuf);
79 }
80 if self.cfg.dat_wrap {
81 cvbuf = res!(Dat::wrap_bytes_var(cvbuf));
82 }
83 chunks.push(cvbuf);
84 }
85
86 Ok((chunks, chunk_state))
87 }
88
89 pub fn keys(
90 &self,
91 id: u64,
92 state: &ChunkState,
93 )
94 -> Outcome<Vec<Dat>>
95 {
96 let mut keys = Vec::with_capacity(state.num_chunks);
97 keys.push(
98 Dat::Tup5u64([
99 id,
100 0,
101 state.data_len as u64,
102 state.num_chunks as u64,
103 state.chunk_size as u64,
104 ])
105 );
106
107 for i in 0..state.num_chunks {
108 let key = Dat::Tup5u64([
109 id,
110 (i as u64) + 1,
111 state.data_len as u64,
112 state.num_chunks as u64,
113 state.chunk_size as u64,
114 ]);
115 keys.push(key);
116 }
117
118 Ok(keys)
119 }
120}
121
122#[derive(Clone, Debug, Default)]
123pub struct ChunkState {
124 pub index: usize,
125 pub data_len: usize,
126 pub num_chunks: usize,
127 pub chunk_size: usize,
128}
129
130impl ChunkState {
131
132 pub fn set_index(mut self, index: usize) -> Self {
133 self.index = index;
134 self
135 }
136 pub fn set_num_of_chunks(mut self, num_chunks: usize) -> Self {
137 self.num_chunks = num_chunks;
138 self
139 }
140}
141
142#[derive(Clone, Debug, Default)]
143pub struct ChunkConfig {
144 pub threshold_bytes: usize,
145 pub chunk_size: usize,
146 pub dat_wrap: bool,
147 pub pad_last: bool,
148}
149
150impl ChunkConfig {
151 pub fn set_size(mut self, chunk_size: usize) -> Self {
152 self.chunk_size = chunk_size;
153 self
154 }
155 pub fn set_pad_last(mut self, pad_last: bool) -> Self {
156 self.pad_last = pad_last;
157 self
158 }
159}