codemem_engine/consolidation/
decay.rs1use super::ConsolidationResult;
2use crate::CodememEngine;
3use codemem_core::CodememError;
4use serde_json::json;
5
6impl CodememEngine {
7 pub fn consolidate_decay(
9 &self,
10 threshold_days: Option<i64>,
11 ) -> Result<ConsolidationResult, CodememError> {
12 let threshold_days = threshold_days.unwrap_or(30);
13 let now = chrono::Utc::now();
14 let threshold_ts = (now - chrono::Duration::days(threshold_days)).timestamp();
15
16 let stale = self.storage.get_stale_memories_for_decay(threshold_ts)?;
17
18 if stale.is_empty() {
19 if let Err(e) = self.storage.insert_consolidation_log("decay", 0) {
20 tracing::warn!("Failed to log decay consolidation: {e}");
21 }
22 return Ok(ConsolidationResult {
23 cycle: "decay".to_string(),
24 affected: 0,
25 details: json!({
26 "threshold_days": threshold_days,
27 }),
28 });
29 }
30
31 let now_ts = now.timestamp();
33 let updates: Vec<(String, f64)> = stale
34 .iter()
35 .map(|(id, importance, access_count, last_accessed_at)| {
36 let days_since = (now_ts - last_accessed_at) as f64 / 86400.0;
37 let time_decay = 0.9_f64.powf(days_since / 30.0);
38 let access_boost = 1.0 + ((*access_count).max(1) as f64).log2() * 0.1;
39 let new_importance = (importance * time_decay * access_boost).clamp(0.0, 1.0);
40 (id.clone(), new_importance)
41 })
42 .collect();
43
44 let affected = self.storage.batch_update_importance(&updates)?;
45
46 if let Err(e) = self.storage.insert_consolidation_log("decay", affected) {
47 tracing::warn!("Failed to log decay consolidation: {e}");
48 }
49
50 Ok(ConsolidationResult {
51 cycle: "decay".to_string(),
52 affected,
53 details: json!({
54 "threshold_days": threshold_days,
55 "algorithm": "power_law",
56 }),
57 })
58 }
59}