use std::path::{Path, PathBuf};
use std::time::SystemTime;
use anyhow::Result;
use walkdir::WalkDir;
use crate::registered_roots;
pub struct IndexStatus {
pub num_docs: u64,
pub roots: Vec<PathBuf>,
pub disk_size_bytes: u64,
pub last_updated: Option<SystemTime>,
}
pub fn index_status(index_dir: &Path) -> Result<IndexStatus> {
let roots = registered_roots(index_dir)?;
let mut disk_size_bytes = 0u64;
let mut last_updated: Option<SystemTime> = None;
for entry in WalkDir::new(index_dir).into_iter().filter_map(|e| e.ok()) {
if !entry.file_type().is_file() {
continue;
}
let Ok(meta) = entry.metadata() else {
continue;
};
disk_size_bytes += meta.len();
if let Ok(modified) = meta.modified() {
last_updated = Some(match last_updated {
Some(prev) if prev >= modified => prev,
_ => modified,
});
}
}
let num_docs = crate::Searcher::open(index_dir)?.num_docs();
Ok(IndexStatus {
num_docs,
roots,
disk_size_bytes,
last_updated,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn index_status_on_missing_index_errors() {
let index_dir = tempfile::tempdir().unwrap();
let missing = index_dir.path().join("no-such-index");
assert!(index_status(&missing).is_err());
}
#[test]
fn index_status_reports_docs_roots_and_nonzero_disk_size() -> Result<()> {
let index_dir = tempfile::tempdir()?;
let target_dir = tempfile::Builder::new().prefix("dowse-test-").tempdir()?;
std::fs::write(target_dir.path().join("note.md"), "内容")?;
crate::rebuild_index(index_dir.path(), target_dir.path())?;
let status = index_status(index_dir.path())?;
assert_eq!(status.num_docs, 1);
assert_eq!(status.roots, vec![target_dir.path().to_path_buf()]);
assert!(status.disk_size_bytes > 0, "刚建的索引落盘体积不应为 0");
assert!(status.last_updated.is_some());
Ok(())
}
}