pub struct DeltaEncoder;
impl DeltaEncoder {
pub fn detect_monotonic(data: &[u32]) -> bool {
if data.len() < 2 {
return false;
}
let mut monotonic_count = 0;
for i in 1..data.len() {
if data[i] >= data[i - 1] {
monotonic_count += 1;
}
}
let ratio = monotonic_count as f64 / (data.len() - 1) as f64;
ratio > 0.9
}
pub fn encode_deltas(data: &[u32]) -> Vec<u32> {
let mut result = vec![];
if data.is_empty() {
return result;
}
result.push(data[0]);
for i in 1..data.len() {
let delta = data[i].saturating_sub(data[i - 1]);
result.push(delta);
}
result
}
pub fn decode_deltas(encoded: &[u32]) -> Vec<u32> {
let mut result = vec![];
if encoded.is_empty() {
return result;
}
result.push(encoded[0]);
for i in 1..encoded.len() {
let value = result[i - 1].saturating_add(encoded[i]);
result.push(value);
}
result
}
pub fn encode_double_deltas(data: &[u32]) -> Vec<u32> {
let deltas = Self::encode_deltas(data);
let double_deltas = Self::encode_deltas(&deltas);
double_deltas
}
pub fn estimate_gain(data: &[u32]) -> f64 {
if !Self::detect_monotonic(data) {
return 0.0; }
let deltas = Self::encode_deltas(data);
let avg_delta: u32 = if deltas.len() > 1 {
deltas[1..].iter().sum::<u32>() / (deltas.len() - 1) as u32
} else {
0
};
if avg_delta < 100 {
0.5 } else if avg_delta < 10000 {
0.2 } else {
0.0 }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_delta_encoding() {
let data = vec![100, 103, 105, 108, 110];
let encoded = DeltaEncoder::encode_deltas(&data);
assert_eq!(encoded[0], 100); assert_eq!(encoded[1], 3); assert_eq!(encoded[2], 2); }
#[test]
fn test_delta_decoding() {
let original = vec![100, 103, 105, 108, 110];
let encoded = DeltaEncoder::encode_deltas(&original);
let decoded = DeltaEncoder::decode_deltas(&encoded);
assert_eq!(original, decoded);
}
#[test]
fn test_monotonic_detection() {
let monotonic = vec![1, 2, 3, 4, 5];
assert!(DeltaEncoder::detect_monotonic(&monotonic));
let random = vec![5, 1, 3, 2, 4];
assert!(!DeltaEncoder::detect_monotonic(&random));
}
}