use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
-use std::time::{Duration, Instant};
+use std::time::{Duration, SystemTime};
pub struct Fileset {
fs_path: PathBuf,
- last_reload: Instant,
+ last_reload: SystemTime,
reload_interval: Duration,
- readers: Mutex<HashMap<PathBuf, (Reader<Mmap>, Instant)>>,
- merger: Mutex<Option<Merger<Reader<Mmap>>>>,
+ readers: Mutex<HashMap<PathBuf, (Reader<Mmap>, SystemTime)>>,
}
fn load_fs_file(f: impl AsRef<Path>) -> Result<Vec<PathBuf>> {
impl Fileset {
pub fn new(fname: impl AsRef<Path>) -> Self {
- let mut res = Self {
+ Self {
fs_path: PathBuf::new().with_file_name(fname.as_ref()),
- last_reload: Instant::now(),
+ last_reload: SystemTime::now() - Duration::new(2, 0),
reload_interval: Duration::new(1, 0),
readers: Mutex::new(HashMap::new()),
- merger: Mutex::new(None),
- };
- res.force_reload();
- res
+ }
}
- fn force_reload(&mut self) {
- let files = load_fs_file(&self.fs_path).unwrap();
- let now = Instant::now();
+ pub fn reload_interval(mut self, d: Duration) -> Self {
+ self.reload_interval = d;
+ self
+ }
- let mut readers = self.readers.lock().unwrap();
- if self.last_reload > now {
- return;
+ fn reload(&mut self) -> Result<()> {
+ let now = SystemTime::now();
+ if now.duration_since(self.last_reload)? < self.reload_interval {
+ return Ok(());
}
- files
- .iter()
- .map(|f| match readers.get(f) {
+
+ let mdata = std::fs::metadata(&self.fs_path)?;
+ if !mdata.is_file() {
+ return Err(format!("{:#?} is not a regular file", &self.fs_path).into());
+ }
+
+ if mdata.modified()? <= self.last_reload {
+ self.last_reload = now;
+ return Ok(());
+ }
+
+ let files = load_fs_file(&self.fs_path)?;
+
+ let mut readers = self.readers.lock().unwrap();
+ files.iter().for_each(|f| {
+ match readers.get(f) {
Some(_) => None,
None => readers.insert(f.to_path_buf(), (crate::reader::from_file(f), now)),
- })
- .count(); // must use
+ };
+ });
let clean = readers
.iter()
.filter(|(_, (_, t))| *t < now)
.map(|(f, _)| f.clone())
.collect::<Vec<_>>();
+
clean.iter().for_each(|f| {
readers.remove(f);
()
});
- let mut merger = self.merger.lock().unwrap();
- merger.replace(Merger::from(readers.iter().map(|(_, (r, _))| r.clone())));
+
self.last_reload = now;
+ Ok(())
}
- fn reload(&mut self) {
- if Instant::now().duration_since(self.last_reload) > self.reload_interval {
- self.force_reload();
- }
+ pub fn readers(&mut self) -> Result<Vec<Reader<Mmap>>> {
+ self.reload()?;
+ let readers = self.readers.lock().unwrap();
+ Ok(readers.iter().map(|(_, (r, _))| r.clone()).collect())
+ }
+
+ pub fn merger(&mut self) -> Result<Merger<Reader<Mmap>>> {
+ Ok(Merger::from(self.readers()?))
}
}