Skip to content

Commit 787bbc0

Browse files
committed
caching with timestamp
1 parent bfc68d6 commit 787bbc0

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

src/project_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<'a> ProjectBuilder<'a> {
8989
Ok(EntryType::TeamFile(absolute_path.to_owned(), relative_path.to_owned()))
9090
}
9191
_ if matches_globs(&relative_path, &self.config.owned_globs) && !matches_globs(&relative_path, &self.config.unowned_globs) => {
92-
let project_file = build_project_file(absolute_path.to_path_buf(), false);
92+
let project_file = build_project_file(absolute_path.to_path_buf(), true);
9393
Ok(EntryType::OwnedFile(project_file))
9494
}
9595
_ => Ok(EntryType::NullEntry()),

src/project_file_builder.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
collections::HashMap,
66
fs::{self, File, OpenOptions},
77
io::{BufReader, BufWriter},
8-
path::PathBuf,
8+
path::{Path, PathBuf},
99
sync::Mutex,
1010
};
1111

@@ -22,9 +22,8 @@ pub(crate) fn build_project_file(path: PathBuf, use_cache: bool) -> ProjectFile
2222

2323
let project_file = build_project_file_without_cache(&path);
2424

25-
if let Ok(mut cache) = PROJECT_FILE_CACHE.lock() {
26-
cache.insert(path.clone(), project_file.owner.clone().unwrap());
27-
}
25+
save_project_file_to_cache(&path, &project_file);
26+
2827
project_file
2928
}
3029

@@ -55,13 +54,19 @@ pub(crate) fn build_project_file_without_cache(path: &PathBuf) -> ProjectFile {
5554
ProjectFile { path: path.clone(), owner }
5655
}
5756

57+
#[derive(Clone, serde::Serialize, serde::Deserialize)]
58+
struct CacheEntry {
59+
timestamp: u64,
60+
owner: Option<String>,
61+
}
62+
5863
lazy_static! {
5964
static ref TEAM_REGEX: Regex = Regex::new(r#"^(?:#|//) @team (.*)$"#).expect("error compiling regular expression");
60-
static ref PROJECT_FILE_CACHE: Box<Mutex<HashMap<PathBuf, String>>> =
65+
static ref PROJECT_FILE_CACHE: Box<Mutex<HashMap<PathBuf, CacheEntry>>> =
6166
Box::new(Mutex::new(load_cache().unwrap_or_else(|_| HashMap::with_capacity(10000))));
6267
}
6368

64-
fn load_cache() -> Result<HashMap<PathBuf, String>, Error> {
69+
fn load_cache() -> Result<HashMap<PathBuf, CacheEntry>, Error> {
6570
let cache_path = get_cache_path();
6671
if !cache_path.exists() {
6772
return Ok(HashMap::with_capacity(10000));
@@ -95,12 +100,39 @@ fn get_cache_path() -> PathBuf {
95100

96101
fn get_project_file_from_cache(path: &PathBuf) -> Result<Option<ProjectFile>, Error> {
97102
if let Ok(cache) = PROJECT_FILE_CACHE.lock() {
98-
if let Some(cached_owner) = cache.get(path) {
99-
return Ok(Some(ProjectFile {
100-
path: path.clone(),
101-
owner: Some(cached_owner.clone()),
102-
}));
103+
if let Some(cached_entry) = cache.get(path) {
104+
let timestamp = get_file_timestamp(path)?;
105+
if cached_entry.timestamp == timestamp {
106+
return Ok(Some(ProjectFile {
107+
path: path.clone(),
108+
owner: cached_entry.owner.clone(),
109+
}));
110+
}
103111
}
104112
}
105113
Ok(None)
106114
}
115+
116+
fn save_project_file_to_cache(path: &Path, project_file: &ProjectFile) {
117+
if let Ok(mut cache) = PROJECT_FILE_CACHE.lock() {
118+
if let Ok(timestamp) = get_file_timestamp(path) {
119+
cache.insert(
120+
path.to_path_buf(),
121+
CacheEntry {
122+
timestamp,
123+
owner: project_file.owner.clone(),
124+
},
125+
);
126+
}
127+
}
128+
}
129+
130+
fn get_file_timestamp(path: &Path) -> Result<u64, Error> {
131+
let metadata = fs::metadata(path).change_context(Error::Io)?;
132+
metadata
133+
.modified()
134+
.change_context(Error::Io)?
135+
.duration_since(std::time::UNIX_EPOCH)
136+
.change_context(Error::Io)
137+
.map(|duration| duration.as_secs())
138+
}

0 commit comments

Comments
 (0)