Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_o3db_sync/src/data/core.rs

7.4 KiB, 16 runs

created by r1870400018:783, 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

1//! The database is instantiated with two types for each of the four schemes, e.g.
2//! `EncryptionScheme` and `ENC`. The first is a default Hematite `enum` that provides access to a
3//! range of schemes, but is naturally limited. The second can be a custom type that implements
4//! `Encrypter`. `oxedyne_fe2o3_iop_db::api::RestSchemesOverride` is used to specify an
5//! `oxedyne_fe2o3_core::alt::Override` based on these two scheme types for encryption and key hashing (as
6//! well as an optional change in the database chunking configuration). This allows four
7//! possibilities for changing the scheme used to write and read individual (k, v) pairs:
8//! - a pass-through which defers to the current database-wide scheme,
9//! - use of a different variant of the default scheme (e.g. `EncryptionScheme`),
10//! - use of a different instance of the scheme given at invocation (e.g. `ENC`),
11//! - no scheme (i.e. the identity transformation).
12use crate::{
13 prelude::*,
14 data::cache::KeyVal,
15 file::stored::{
16 StoredKey,
17 StoredValue,
18 },
19};
20
21use oxedyne_fe2o3_crypto::enc::EncryptionScheme;
22use oxedyne_fe2o3_iop_crypto::enc::EncrypterDefAlt;
23use oxedyne_fe2o3_hash::{
24 csum::{
25 ChecksummerDefAlt,
26 ChecksumScheme,
27 },
28 hash::{
29 HasherDefAlt,
30 HashScheme,
31 },
32};
33use oxedyne_fe2o3_iop_db::api::Meta;
34use oxedyne_fe2o3_jdat::{
35 daticle::Dat,
36 id::NumIdDat,
37};
38
39use std::fmt;
40
41#[derive(Clone)]
42pub enum Key {
43 Complete(Vec<u8>),
44 Chunk(Vec<u8>, usize),
45}
46
47impl fmt::Debug for Key {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 Self::Complete(v) => write!(f, "Complete({:02x?})", v),
51 Self::Chunk(v, i) => write!(f, "Chunk({:02x?}, {})", v, i),
52 }
53 }
54}
55
56pub struct Encode;
57
58impl Encode {
59
60 pub fn encode_dat(
61 k: Dat,
62 v: Dat,
63 )
64 -> Outcome<(Vec<u8>, Vec<u8>)>
65 {
66 Ok((res!(k.as_bytes()), res!(v.as_bytes())))
67 }
68
69 pub fn encode<
70 const UIDL: usize,
71 UID: NumIdDat<UIDL>,
72 C: Checksummer,
73 >(
74 mut kv: KeyVal<UIDL, UID>,
75 csummer: ChecksummerDefAlt<ChecksumScheme, C>,
76 )
77 -> Outcome<(
78 Vec<u8>,
79 Vec<u8>,
80 Option<usize>,
81 Meta<UIDL, UID>,
82 usize,
83 usize,
84 usize,
85 )>
86 {
87 res!(kv.stamp_time_now());
88 let KeyVal { key, val, chash, meta, cbpind } = kv;
89 // [1.1] Assemble the StoredKey, StoredValue and StoredIndex to be written to file.
90 let cind = key.index();
91 let mut kbuf = key.into_bytes();
92 kbuf = res!(StoredKey::build_bytes(chash, kbuf, cind, &meta, csummer.clone()));
93 let klen = kbuf.len();
94 let mut vbuf = val;
95 vbuf = res!(StoredValue::build_bytes(vbuf, csummer));
96 let vlen = vbuf.len();
97 Ok((kbuf, vbuf, cind, meta, cbpind, klen, vlen))
98 }
99}
100
101impl Key {
102
103 pub fn as_bytes(&self) -> &Vec<u8> {
104 match self {
105 Self::Complete(byts) => byts,
106 Self::Chunk(byts, _) => byts,
107 }
108 }
109
110 pub fn into_bytes(self) -> Vec<u8> {
111 match self {
112 Self::Complete(byts) => byts,
113 Self::Chunk(byts, _) => byts,
114 }
115 }
116
117 pub fn index(&self) -> Option<usize> {
118 match self {
119 Self::Chunk(_, cind) => Some(*cind),
120 _ => None,
121 }
122 }
123
124 //pub fn stored(&self, chash: alias::ChooseHash, meta: &Meta) -> Outcome<Vec<u8>> {
125 // let kbuf = self.as_bytes().clone();
126 // StoredKey::build_bytes(chash, kbuf, self.index(), meta)
127 //}
128
129 pub fn len(&self) -> usize {
130 match self {
131 Self::Complete(byts) => byts.len(),
132 Self::Chunk(byts, _) => byts.len(),
133 }
134 }
135
136}
137
138#[derive(Clone, Debug)]
139pub enum Value<
140 const UIDL: usize,
141 UID: NumIdDat<UIDL>,
142> {
143 Complete(Option<(Dat, Meta<UIDL, UID>)>, bool),
144 Chunk(Option<(Dat, Meta<UIDL, UID>)>, usize, bool),
145}
146
147impl<
148 const UIDL: usize,
149 UID: NumIdDat<UIDL>,
150>
151 Value<UIDL, UID>
152{
153 pub fn new(
154 data: Option<(Dat, Meta<UIDL, UID>)>,
155 cind: Option<usize>,
156 postgc: bool,
157 )
158 -> Self
159 {
160 match cind {
161 Some(cind) => Self::Chunk(data, cind, postgc),
162 None => Self::Complete(data, postgc),
163 }
164 }
165
166 pub fn data(&self) -> Option<&(Dat, Meta<UIDL, UID>)> {
167 match self {
168 Self::Complete(opt, ..) => opt.as_ref(),
169 Self::Chunk(opt, ..) => opt.as_ref(),
170 }
171 }
172
173 pub fn index(&self) -> Option<usize> {
174 match self {
175 Self::Chunk(_, cind, _) => Some(*cind),
176 _ => None,
177 }
178 }
179}
180
181#[derive(Clone, Debug, Default)]
182pub struct RestSchemesInput<
183 ENC: Encrypter,
184 KH: Hasher,
185 PR: Hasher,
186 CS: Checksummer,
187>{
188 pub enc: Option<ENC>,
189 pub hash: Option<KH>,
190 pub prnd: Option<PR>,
191 pub csum: Option<CS>,
192}
193
194impl<
195 ENC: Encrypter,
196 KH: Hasher,
197 PR: Hasher,
198 CS: Checksummer,
199>
200 RestSchemesInput<ENC, KH, PR, CS>
201{
202 pub fn new(
203 enc: Option<ENC>,
204 hash: Option<KH>,
205 prnd: Option<PR>,
206 csum: Option<CS>,
207 )
208 -> Self
209 {
210 Self {
211 enc,
212 hash,
213 prnd,
214 csum,
215 }
216 }
217}
218
219#[derive(Clone, Debug)]
220pub struct RestSchemes<
221 ENC: Encrypter,
222 KH: Hasher,
223 PR: Hasher,
224 CS: Checksummer,
225>{
226 pub enc: EncrypterDefAlt<EncryptionScheme, ENC>,
227 pub hash: HasherDefAlt<HashScheme, KH>,
228 pub prnd: HasherDefAlt<HashScheme, PR>,
229 pub csum: ChecksummerDefAlt<ChecksumScheme, CS>,
230}
231
232impl<
233 ENC: Encrypter,
234 KH: Hasher,
235 PR: Hasher,
236 CS: Checksummer,
237>
238 Default for RestSchemes<ENC, KH, PR, CS>
239{
240 fn default() -> Self {
241 Self {
242 enc: EncrypterDefAlt(DefAlt::None),
243 hash: HasherDefAlt(DefAlt::Default(HashScheme::new_seahash())),
244 prnd: HasherDefAlt(DefAlt::Default(HashScheme::new_seahash())),
245 csum: ChecksummerDefAlt(DefAlt::Default(ChecksumScheme::new_crc32())),
246 }
247 }
248}
249
250impl<
251 ENC: Encrypter,
252 KH: Hasher,
253 PR: Hasher,
254 CS: Checksummer,
255>
256 From<RestSchemesInput<ENC, KH, PR, CS>> for RestSchemes<ENC, KH, PR, CS>
257{
258 fn from(input: RestSchemesInput<ENC, KH, PR, CS>) -> Self {
259 let mut result = Self::default();
260 result.enc = EncrypterDefAlt::from(input.enc);
261 if input.hash.is_some() { result.hash = HasherDefAlt::from(input.hash); }
262 if input.prnd.is_some() { result.prnd = HasherDefAlt::from(input.prnd); }
263 if input.csum.is_some() { result.csum = ChecksummerDefAlt::from(input.csum); }
264 result
265 }
266}
267
268impl<
269 ENC: Encrypter,
270 KH: Hasher,
271 PR: Hasher,
272 CS: Checksummer,
273>
274 RestSchemes<ENC, KH, PR, CS>
275{
276 pub fn encrypter(&self) -> &EncrypterDefAlt<EncryptionScheme, ENC> { &self.enc }
277 pub fn key_hasher(&self) -> &HasherDefAlt<HashScheme, KH> { &self.hash }
278 pub fn pseudorandom_hasher(&self) -> &HasherDefAlt<HashScheme, PR> { &self.prnd }
279 pub fn checksummer(&self) -> &ChecksummerDefAlt<ChecksumScheme, CS> { &self.csum }
280
281 pub fn set_key_hasher(mut self, hasher: KH) -> Self {
282 self.hash = HasherDefAlt(DefAlt::Given(hasher));
283 self
284 }
285}