use super::constants::*;
pub fn calculate_schema_stability_score(
total_changes: usize,
breaking_changes: usize,
frequency: f64,
days_since_last: f64,
) -> f64 {
let mut score: f64 = 1.0;
if total_changes > SCHEMA_CHANGES_HIGH_THRESHOLD {
score -= 0.3;
} else if total_changes > SCHEMA_CHANGES_MEDIUM_THRESHOLD {
score -= 0.2;
} else if total_changes > SCHEMA_CHANGES_LOW_THRESHOLD {
score -= 0.1;
}
if breaking_changes > BREAKING_CHANGES_HIGH_THRESHOLD {
score -= 0.4;
} else if breaking_changes > BREAKING_CHANGES_MEDIUM_THRESHOLD {
score -= 0.3;
} else if breaking_changes > 0 {
score -= 0.2;
}
if frequency > SCHEMA_CHANGE_FREQUENCY_HIGH {
score -= 0.3;
} else if frequency > SCHEMA_CHANGE_FREQUENCY_MEDIUM {
score -= 0.2;
} else if frequency > SCHEMA_CHANGE_FREQUENCY_LOW {
score -= 0.1;
}
if days_since_last > DAYS_SINCE_CHANGE_VERY_STABLE {
score += 0.1;
} else if days_since_last > DAYS_SINCE_CHANGE_STABLE {
score += 0.05;
}
score.clamp(0.0_f64, 1.0_f64)
}
pub fn calculate_storage_cost_impact(
total_size: u64,
snapshot_count: usize,
oldest_age: f64,
) -> f64 {
let mut impact: f64 = 0.0;
let size_gb = total_size as f64 / (1024.0 * 1024.0 * 1024.0);
if size_gb > STORAGE_SIZE_HIGH_GB {
impact += 0.4;
} else if size_gb > STORAGE_SIZE_MEDIUM_GB {
impact += 0.3;
} else if size_gb > STORAGE_SIZE_LOW_GB {
impact += 0.2;
}
if snapshot_count > SNAPSHOT_COUNT_HIGH {
impact += 0.3;
} else if snapshot_count > SNAPSHOT_COUNT_MEDIUM {
impact += 0.2;
} else if snapshot_count > SNAPSHOT_COUNT_LOW {
impact += 0.1;
}
if oldest_age > SNAPSHOT_AGE_OLD_DAYS {
impact += 0.3;
} else if oldest_age > SNAPSHOT_AGE_MEDIUM_DAYS {
impact += 0.2;
}
impact.clamp(0.0_f64, 1.0_f64)
}
pub fn calculate_retention_efficiency(
snapshot_count: usize,
oldest_age: f64,
newest_age: f64,
) -> f64 {
let mut efficiency: f64 = 1.0;
if snapshot_count > RETENTION_SNAPSHOT_VERY_HIGH {
efficiency -= RETENTION_PENALTY_VERY_HIGH;
} else if snapshot_count > RETENTION_SNAPSHOT_HIGH {
efficiency -= RETENTION_PENALTY_HIGH;
} else if snapshot_count > RETENTION_SNAPSHOT_MEDIUM {
efficiency -= RETENTION_PENALTY_MEDIUM;
} else if snapshot_count > RETENTION_SNAPSHOT_LOW {
efficiency -= RETENTION_PENALTY_LOW;
}
let retention_days = oldest_age - newest_age;
if retention_days > RETENTION_MAX_DAYS {
efficiency -= RETENTION_TOO_LONG_PENALTY; } else if retention_days < RETENTION_MIN_DAYS {
efficiency -= RETENTION_TOO_SHORT_PENALTY; }
efficiency.clamp(0.0_f64, 1.0_f64)
}
pub fn calculate_recommended_retention(snapshot_count: usize, oldest_age: f64) -> u64 {
if snapshot_count > RETENTION_SNAPSHOT_VERY_HIGH
|| oldest_age > RECOMMENDED_RETENTION_VERY_OLD_DAYS
{
RECOMMENDED_RETENTION_SHORT } else if snapshot_count > RETENTION_SNAPSHOT_HIGH
|| oldest_age > RECOMMENDED_RETENTION_OLD_DAYS
{
RECOMMENDED_RETENTION_MEDIUM } else if snapshot_count > RETENTION_SNAPSHOT_MEDIUM
|| oldest_age > RECOMMENDED_RETENTION_RECENT_DAYS
{
RECOMMENDED_RETENTION_LONG } else {
RECOMMENDED_RETENTION_VERY_LONG }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_schema_stability_perfect_score() {
let score = calculate_schema_stability_score(0, 0, 0.0, 60.0);
assert!((score - 1.0).abs() < 0.01); }
#[test]
fn test_schema_stability_with_breaking_changes() {
let score = calculate_schema_stability_score(5, 3, 0.05, 10.0);
assert!(score < 1.0);
assert!(score > 0.0);
}
#[test]
fn test_schema_stability_high_frequency() {
let score = calculate_schema_stability_score(100, 20, 2.0, 1.0);
assert!(score < 0.5);
}
#[test]
fn test_storage_cost_impact_low() {
let impact = calculate_storage_cost_impact(1024 * 1024, 5, 7.0);
assert!(impact < 0.3);
}
#[test]
fn test_storage_cost_impact_high() {
let impact = calculate_storage_cost_impact(200 * 1024 * 1024 * 1024, 150, 120.0);
assert!(impact > 0.8);
}
#[test]
fn test_retention_efficiency_perfect() {
let efficiency = calculate_retention_efficiency(10, 30.0, 0.0);
assert!((0.9..=1.0).contains(&efficiency));
}
#[test]
fn test_retention_efficiency_too_many_snapshots() {
let efficiency = calculate_retention_efficiency(1500, 30.0, 0.0);
assert!(efficiency < 0.7);
}
#[test]
fn test_retention_efficiency_too_long_retention() {
let efficiency = calculate_retention_efficiency(10, 400.0, 0.0);
assert!(efficiency < 1.0);
}
#[test]
fn test_retention_efficiency_too_short_retention() {
let efficiency = calculate_retention_efficiency(10, 5.0, 0.0);
assert!(efficiency < 1.0);
}
#[test]
fn test_recommended_retention_few_snapshots_recent() {
let retention = calculate_recommended_retention(10, 20.0);
assert_eq!(retention, RECOMMENDED_RETENTION_VERY_LONG); }
#[test]
fn test_recommended_retention_moderate_snapshots() {
let retention = calculate_recommended_retention(150, 20.0);
assert_eq!(retention, RECOMMENDED_RETENTION_LONG); }
#[test]
fn test_recommended_retention_high_snapshots() {
let retention = calculate_recommended_retention(600, 20.0);
assert_eq!(retention, RECOMMENDED_RETENTION_MEDIUM); }
#[test]
fn test_recommended_retention_very_high_snapshots() {
let retention = calculate_recommended_retention(1500, 20.0);
assert_eq!(retention, RECOMMENDED_RETENTION_SHORT); }
#[test]
fn test_recommended_retention_very_old_data() {
let retention = calculate_recommended_retention(10, 400.0);
assert_eq!(retention, RECOMMENDED_RETENTION_SHORT); }
}