DEV: for the repl use case allow changed file reimports.

Closes #47
This commit is contained in:
Jeremy Wall 2019-05-28 19:54:12 -05:00
parent 1589aaf7d7
commit 879a8d2100
2 changed files with 44 additions and 7 deletions

View File

@ -34,17 +34,21 @@ pub type Result<T> = result::Result<T, io::Error>;
pub trait Cache {
fn has_path(&self, path: &PathBuf) -> Result<bool>;
fn get(&self, path: &PathBuf) -> Result<Option<Rc<Val>>>;
fn stash(&mut self, path: PathBuf, asset: Rc<Val>) -> Result<()>;
fn stash(&mut self, path: PathBuf, asset: Rc<Val>, modkey: u64) -> Result<()>;
fn evict(&mut self, path: &PathBuf) -> Result<()>;
fn check_mod_key(&self, path: &PathBuf, modkey: u64) -> Result<bool>;
}
pub struct MemoryCache {
map: HashMap<PathBuf, Rc<Val>>,
mod_key_map: HashMap<PathBuf, u64>,
}
impl MemoryCache {
pub fn new() -> Self {
MemoryCache {
map: HashMap::new(),
mod_key_map: HashMap::new(),
}
}
}
@ -58,8 +62,23 @@ impl Cache for MemoryCache {
Ok(self.map.get(path).map(|v| v.clone()))
}
fn stash(&mut self, path: PathBuf, asset: Rc<Val>) -> Result<()> {
self.map.insert(path, asset);
fn stash(&mut self, path: PathBuf, asset: Rc<Val>, modkey: u64) -> Result<()> {
self.map.insert(path.clone(), asset);
self.mod_key_map.insert(path, modkey);
Ok(())
}
fn evict(&mut self, path: &PathBuf) -> Result<()> {
self.map.remove(path);
self.mod_key_map.remove(path);
Ok(())
}
fn check_mod_key(&self, path: &PathBuf, modkey: u64) -> Result<bool> {
Ok(self
.mod_key_map
.get(path)
.map(|v| *v == modkey)
.unwrap_or(true))
}
}

View File

@ -415,7 +415,9 @@ where
}
};
let mut mut_assets_cache = self.assets.borrow_mut();
mut_assets_cache.stash(path, result.clone())?;
// standard library assets are not real files so the
// mod key is always 0.
mut_assets_cache.stash(path, result.clone(), 0)?;
return Ok(result);
} else {
return Err(error::BuildError::with_pos(
@ -453,8 +455,24 @@ where
)
.to_boxed());
}
// Introduce a scope so the above borrow is dropped before we modify
// the cache below.
// 1. calculate mod time for file.
let lib_meta = std::fs::metadata(&normalized)?;
let modkey = lib_meta
.modified()?
.duration_since(std::time::SystemTime::UNIX_EPOCH)?
.as_secs();
{
eprintln!("{} modkey...", modkey);
// 2. check mod time against previous stored mod time for file.
if !self.assets.borrow().check_mod_key(&normalized, modkey)? {
// 3. if different then evict from the cache
eprintln!(
"{} has changed evicting from cache...",
normalized.to_string_lossy().to_string()
);
self.assets.borrow_mut().evict(&normalized)?;
}
}
// Only parse the file once on import.
let maybe_asset = self.assets.borrow().get(&normalized)?;
let result = match maybe_asset {
@ -480,7 +498,7 @@ where
}
};
let mut mut_assets_cache = self.assets.borrow_mut();
mut_assets_cache.stash(normalized.clone(), result.clone())?;
mut_assets_cache.stash(normalized.clone(), result.clone(), modkey)?;
return Ok(result);
}