use amaters_core::Update as UpdateOp;
use amaters_core::types::{CipherBlob, Key};
#[derive(Debug, Clone)]
pub struct StreamConfig {
pub chunk_size: usize,
pub max_results: Option<usize>,
pub timeout: std::time::Duration,
}
impl Default for StreamConfig {
fn default() -> Self {
Self {
chunk_size: 100,
max_results: None,
timeout: std::time::Duration::from_secs(30),
}
}
}
impl StreamConfig {
pub fn with_chunk_size(mut self, chunk_size: usize) -> Self {
self.chunk_size = if chunk_size == 0 { 1 } else { chunk_size };
self
}
pub fn with_max_results(mut self, max_results: usize) -> Self {
self.max_results = Some(max_results);
self
}
pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
self.timeout = timeout;
self
}
}
#[derive(Debug)]
#[allow(clippy::enum_variant_names)]
pub(crate) enum RollbackOp {
UndoSet {
key: Key,
old_value: Option<CipherBlob>,
},
UndoDelete {
key: Key,
old_value: Option<CipherBlob>,
},
UndoUpdate {
snapshots: Vec<(Key, Option<CipherBlob>)>,
},
}
pub(crate) fn apply_update_operation(current: &CipherBlob, op: &UpdateOp) -> CipherBlob {
match op {
UpdateOp::Set(_col, blob) => blob.clone(),
UpdateOp::Add(_col, blob) => {
let a = current.as_bytes();
let b = blob.as_bytes();
let len = a.len().max(b.len());
let mut result = Vec::with_capacity(len);
for i in 0..len {
let va = if i < a.len() { a[i] } else { 0 };
let vb = if i < b.len() { b[i] } else { 0 };
result.push(va.wrapping_add(vb));
}
CipherBlob::new(result)
}
UpdateOp::Mul(_col, blob) => {
let a = current.as_bytes();
let b = blob.as_bytes();
let len = a.len().max(b.len());
let mut result = Vec::with_capacity(len);
for i in 0..len {
let va = if i < a.len() { a[i] } else { 1 };
let vb = if i < b.len() { b[i] } else { 1 };
result.push(va.wrapping_mul(vb));
}
CipherBlob::new(result)
}
}
}