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). |
| 12 | use crate::{ |
| 13 | prelude::*, |
| 14 | data::cache::KeyVal, |
| 15 | file::stored::{ |
| 16 | StoredKey, |
| 17 | StoredValue, |
| 18 | }, |
| 19 | }; |
| 20 | |
| 21 | use oxedyne_fe2o3_crypto::enc::EncryptionScheme; |
| 22 | use oxedyne_fe2o3_iop_crypto::enc::EncrypterDefAlt; |
| 23 | use oxedyne_fe2o3_hash::{ |
| 24 | csum::{ |
| 25 | ChecksummerDefAlt, |
| 26 | ChecksumScheme, |
| 27 | }, |
| 28 | hash::{ |
| 29 | HasherDefAlt, |
| 30 | HashScheme, |
| 31 | }, |
| 32 | }; |
| 33 | use oxedyne_fe2o3_iop_db::api::Meta; |
| 34 | use oxedyne_fe2o3_jdat::{ |
| 35 | daticle::Dat, |
| 36 | id::NumIdDat, |
| 37 | }; |
| 38 | |
| 39 | use std::fmt; |
| 40 | |
| 41 | #[derive(Clone)] |
| 42 | pub enum Key { |
| 43 | Complete(Vec<u8>), |
| 44 | Chunk(Vec<u8>, usize), |
| 45 | } |
| 46 | |
| 47 | impl 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 | |
| 56 | pub struct Encode; |
| 57 | |
| 58 | impl 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 | |
| 101 | impl 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)] |
| 139 | pub 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 | |
| 147 | impl< |
| 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)] |
| 182 | pub 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 | |
| 194 | impl< |
| 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)] |
| 220 | pub 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 | |
| 232 | impl< |
| 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 | |
| 250 | impl< |
| 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 | |
| 268 | impl< |
| 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 | } |