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 { pub trait Cache {
fn has_path(&self, path: &PathBuf) -> Result<bool>; fn has_path(&self, path: &PathBuf) -> Result<bool>;
fn get(&self, path: &PathBuf) -> Result<Option<Rc<Val>>>; 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 { pub struct MemoryCache {
map: HashMap<PathBuf, Rc<Val>>, map: HashMap<PathBuf, Rc<Val>>,
mod_key_map: HashMap<PathBuf, u64>,
} }
impl MemoryCache { impl MemoryCache {
pub fn new() -> Self { pub fn new() -> Self {
MemoryCache { MemoryCache {
map: HashMap::new(), 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())) Ok(self.map.get(path).map(|v| v.clone()))
} }
fn stash(&mut self, path: PathBuf, asset: Rc<Val>) -> Result<()> { fn stash(&mut self, path: PathBuf, asset: Rc<Val>, modkey: u64) -> Result<()> {
self.map.insert(path, asset); self.map.insert(path.clone(), asset);
self.mod_key_map.insert(path, modkey);
Ok(()) 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(); 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); return Ok(result);
} else { } else {
return Err(error::BuildError::with_pos( return Err(error::BuildError::with_pos(
@ -453,8 +455,24 @@ where
) )
.to_boxed()); .to_boxed());
} }
// Introduce a scope so the above borrow is dropped before we modify // 1. calculate mod time for file.
// the cache below. 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. // Only parse the file once on import.
let maybe_asset = self.assets.borrow().get(&normalized)?; let maybe_asset = self.assets.borrow().get(&normalized)?;
let result = match maybe_asset { let result = match maybe_asset {
@ -480,7 +498,7 @@ where
} }
}; };
let mut mut_assets_cache = self.assets.borrow_mut(); 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); return Ok(result);
} }