use anyhow::Result;
use super::persistence::{
indexes_toml_path, load_index_registry_at, upsert_index_registry_entry_at, PersistedIndex,
};
pub fn warmboot_sort_key(entry: &PersistedIndex) -> u64 {
let q = entry.last_queried_unix.unwrap_or(0);
let i = entry.last_indexed_unix.unwrap_or(0);
q.max(i)
}
pub fn read_last_queried_unix(index_id: &str) -> Option<u64> {
let Ok(path) = indexes_toml_path() else {
return None;
};
let entries = load_index_registry_at(&path).ok()?;
entries
.into_iter()
.find(|e| e.id == index_id)
.and_then(|e| e.last_queried_unix)
}
pub fn update_last_queried_unix(index_id: &str, now_unix: u64) -> Result<()> {
let path = indexes_toml_path()?;
let mut entries = load_index_registry_at(&path).unwrap_or_default();
let Some(entry) = entries.iter_mut().find(|e| e.id == index_id) else {
return Ok(()); };
entry.last_queried_unix = Some(now_unix);
let updated = entry.clone();
upsert_index_registry_entry_at(&path, updated)
}
pub fn update_last_indexed_unix(index_id: &str, now_unix: u64) -> Result<()> {
let path = indexes_toml_path()?;
let mut entries = load_index_registry_at(&path).unwrap_or_default();
let Some(entry) = entries.iter_mut().find(|e| e.id == index_id) else {
return Ok(());
};
entry.last_indexed_unix = Some(now_unix);
let updated = entry.clone();
upsert_index_registry_entry_at(&path, updated)
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::*;
use crate::service::persistence::{load_index_registry_at, save_index_registry_at};
#[test]
fn last_queried_and_indexed_round_trips() {
use crate::service::persistence::PersistedIndex;
assert!(PersistedIndex::default().last_queried_unix.is_none());
assert!(PersistedIndex::default().last_indexed_unix.is_none());
let tmp = tempfile::NamedTempFile::new().unwrap();
let path = tmp.path().to_path_buf();
std::fs::write(
&path,
r#"
[[index]]
id = "legacy"
root_path = "/tmp/legacy_ts"
"#,
)
.unwrap();
let entries = load_index_registry_at(&path).unwrap();
assert_eq!(entries.len(), 1);
assert!(
entries[0].last_queried_unix.is_none(),
"missing field must default to None (issue #993 back-compat)"
);
assert!(entries[0].last_indexed_unix.is_none());
let tmp = tempfile::NamedTempFile::new().unwrap();
let path = tmp.path().to_path_buf();
save_index_registry_at(
&path,
&[PersistedIndex {
id: "queried".into(),
root_path: PathBuf::from("/tmp/q"),
last_queried_unix: Some(1_700_000_000),
last_indexed_unix: Some(1_699_000_000),
..Default::default()
}],
)
.unwrap();
let entries = load_index_registry_at(&path).unwrap();
assert_eq!(entries.len(), 1);
assert_eq!(entries[0].last_queried_unix, Some(1_700_000_000));
assert_eq!(entries[0].last_indexed_unix, Some(1_699_000_000));
}
#[test]
fn warmboot_sort_key_prefers_most_recent_activity() {
use crate::service::persistence::PersistedIndex;
let mk = |q: Option<u64>, i: Option<u64>| PersistedIndex {
id: "x".into(),
root_path: PathBuf::from("/x"),
last_queried_unix: q,
last_indexed_unix: i,
..Default::default()
};
assert_eq!(warmboot_sort_key(&mk(None, None)), 0);
assert_eq!(warmboot_sort_key(&mk(Some(100), None)), 100);
assert_eq!(warmboot_sort_key(&mk(None, Some(200))), 200);
assert_eq!(warmboot_sort_key(&mk(Some(300), Some(200))), 300);
assert_eq!(warmboot_sort_key(&mk(Some(100), Some(400))), 400);
}
}