Skip to main content

devscout_rs/graph/
cache.rs

1use std::fs;
2use std::io;
3use std::path::Path;
4
5use serde::{Deserialize, Serialize};
6
7use super::fragment_types::AnyFragment;
8use super::ordered::OrderedMap;
9use super::paths::{atomic_write_json, fragments_cache_path, fragments_index_path};
10use super::rebuild::GraphFile;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13/// Represents `FragmentCacheEntry`.
14pub struct FragmentCacheEntry {
15    /// The mtime value.
16    pub mtime: i64,
17    /// The fragment value.
18    pub fragment: AnyFragment,
19}
20
21pub(crate) fn read_fragments_cache(root: &Path) -> OrderedMap<FragmentCacheEntry> {
22    match fs::read_to_string(fragments_cache_path(root)) {
23        Ok(text) => serde_json::from_str(&text).unwrap_or_default(),
24        Err(_) => OrderedMap::default(),
25    }
26}
27
28pub(crate) fn write_fragments_cache(
29    root: &Path,
30    cache: &OrderedMap<FragmentCacheEntry>,
31) -> io::Result<()> {
32    atomic_write_json(&fragments_cache_path(root), cache)
33}
34
35/// Read the fragments index (rel -> mtime). Used for the per-file reuse
36/// decision, independent of the graph rebuild.
37pub fn read_fragments_index(root: &Path) -> OrderedMap<i64> {
38    match fs::read_to_string(fragments_index_path(root)) {
39        Ok(text) => serde_json::from_str(&text).unwrap_or_default(),
40        Err(_) => OrderedMap::default(),
41    }
42}
43
44pub(crate) fn write_fragments_index(
45    root: &Path,
46    cache: &OrderedMap<FragmentCacheEntry>,
47) -> io::Result<()> {
48    let mut index = OrderedMap::new();
49    for (rel, entry) in cache.iter() {
50        index.insert(rel.clone(), entry.mtime);
51    }
52    atomic_write_json(&fragments_index_path(root), &index)
53}
54
55/// Whether the fragments index is stale for the given graph files (any mtime
56/// mismatch, or a differing file count).
57pub fn index_is_stale(index: &OrderedMap<i64>, graph_files: &[GraphFile]) -> bool {
58    graph_files
59        .iter()
60        .any(|f| index.get(&f.rel) != Some(&f.mtime))
61        || index.len() != graph_files.len()
62}