melib: track modified paths in maildir

Keep modified path status in maildir to prevent not-found panics
embed
Manos Pitsidianakis 2019-05-26 02:25:30 +03:00
parent d8651db93a
commit eff1c1641c
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 57 additions and 17 deletions

View File

@ -73,7 +73,11 @@ impl MaildirOp {
debug!("{:#?}", e); debug!("{:#?}", e);
} }
} }
map.get(&self.hash).unwrap().clone() if let Some(path) = &map[&self.hash].modified {
path.clone()
} else {
map.get(&self.hash).unwrap().buf.to_path_buf()
}
} }
} }
@ -161,13 +165,12 @@ impl<'a> BackendOp for MaildirOp {
debug!("success in rename"); debug!("success in rename");
let old_hash = envelope.hash(); let old_hash = envelope.hash();
let new_name: PathBuf = new_name.into(); let new_name: PathBuf = new_name.into();
let new_hash = get_file_hash(&new_name);
envelope.set_hash(new_hash);
let hash_index = self.hash_index.clone(); let hash_index = self.hash_index.clone();
let mut map = hash_index.lock().unwrap(); let mut map = hash_index.lock().unwrap();
let map = map.entry(self.folder_hash).or_default(); let map = map.entry(self.folder_hash).or_default();
map.insert(old_hash, new_name.clone()); if let maildir_path = map.entry(old_hash).or_default() {
map.insert(new_hash, new_name); maildir_path.modified = Some(new_name.clone().into());
}
Ok(()) Ok(())
} }
} }

View File

@ -48,21 +48,49 @@ use std::result;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
#[derive(Debug, Default)]
pub struct MaildirPath {
pub(super) buf: PathBuf,
pub(super) modified: Option<PathBuf>,
}
impl Deref for MaildirPath {
type Target = PathBuf;
fn deref(&self) -> &PathBuf {
&self.buf
}
}
impl DerefMut for MaildirPath {
fn deref_mut(&mut self) -> &mut PathBuf {
&mut self.buf
}
}
impl From<PathBuf> for MaildirPath {
fn from(val: PathBuf) -> MaildirPath {
MaildirPath {
buf: val,
modified: None,
}
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct HashIndex { pub struct HashIndex {
index: FnvHashMap<EnvelopeHash, PathBuf>, index: FnvHashMap<EnvelopeHash, MaildirPath>,
hash: FolderHash, hash: FolderHash,
} }
impl Deref for HashIndex { impl Deref for HashIndex {
type Target = FnvHashMap<EnvelopeHash, PathBuf>; type Target = FnvHashMap<EnvelopeHash, MaildirPath>;
fn deref(&self) -> &FnvHashMap<EnvelopeHash, PathBuf> { fn deref(&self) -> &FnvHashMap<EnvelopeHash, MaildirPath> {
&self.index &self.index
} }
} }
impl DerefMut for HashIndex { impl DerefMut for HashIndex {
fn deref_mut(&mut self) -> &mut FnvHashMap<EnvelopeHash, PathBuf> { fn deref_mut(&mut self) -> &mut FnvHashMap<EnvelopeHash, MaildirPath> {
&mut self.index &mut self.index
} }
} }
@ -227,10 +255,10 @@ impl MailBackend for MaildirType {
/* Linear search in hash_index to find old hash */ /* Linear search in hash_index to find old hash */
let old_hash: EnvelopeHash = { let old_hash: EnvelopeHash = {
if let Some((k, v)) = if let Some((k, v)) =
index_lock.iter_mut().find(|(_, v)| **v == pathbuf) index_lock.iter_mut().find(|(_, v)| *v.buf == pathbuf)
{ {
//TODO FIXME This doesn't make sense? //TODO FIXME This doesn't make sense?
*v = pathbuf.clone(); *v = pathbuf.clone().into();
*k *k
} else { } else {
/* Did we just miss a Create event? In any case, create /* Did we just miss a Create event? In any case, create
@ -269,7 +297,7 @@ impl MailBackend for MaildirType {
"hash {}, path: {:?} couldn't be parsed", "hash {}, path: {:?} couldn't be parsed",
new_hash, &pathbuf new_hash, &pathbuf
); );
index_lock.insert(new_hash, pathbuf); index_lock.insert(new_hash, pathbuf.into());
/* Send Write notice */ /* Send Write notice */
@ -288,13 +316,22 @@ impl MailBackend for MaildirType {
let mut hash_indexes_lock = hash_indexes.lock().unwrap(); let mut hash_indexes_lock = hash_indexes.lock().unwrap();
let index_lock = hash_indexes_lock.entry(folder_hash).or_default(); let index_lock = hash_indexes_lock.entry(folder_hash).or_default();
let hash: EnvelopeHash = if let Some((k, _)) = let hash: EnvelopeHash = if let Some((k, _)) =
index_lock.iter().find(|(_, v)| **v == pathbuf) index_lock.iter().find(|(_, v)| *v.buf == pathbuf)
{ {
*k *k
} else { } else {
debug!("removed but not contained in index"); debug!("removed but not contained in index");
continue; continue;
}; };
if let Some(path) = &index_lock[&hash].modified {
debug!(
"envelope {} has modified path set {}",
hash,
path.display()
);
continue;
}
index_lock.remove(&hash); index_lock.remove(&hash);
sender.send(RefreshEvent { sender.send(RefreshEvent {
@ -322,7 +359,7 @@ impl MailBackend for MaildirType {
kind: Rename(old_hash, new_hash), kind: Rename(old_hash, new_hash),
}); });
index_lock.remove(&old_hash); index_lock.remove(&old_hash);
index_lock.insert(new_hash, dest); index_lock.insert(new_hash, dest.into());
continue; continue;
} else if !index_lock.contains_key(&new_hash) { } else if !index_lock.contains_key(&new_hash) {
debug!("not contains_new_key"); debug!("not contains_new_key");
@ -618,7 +655,7 @@ impl MaildirType {
let mut map = map.lock().unwrap(); let mut map = map.lock().unwrap();
let map = map.entry(folder_hash).or_default(); let map = map.entry(folder_hash).or_default();
let hash = env.hash(); let hash = env.hash();
map.insert(hash, file.clone()); map.insert(hash, file.clone().into());
local_r.push(env); local_r.push(env);
continue; continue;
} }
@ -627,7 +664,7 @@ impl MaildirType {
{ {
let mut map = map.lock().unwrap(); let mut map = map.lock().unwrap();
let map = map.entry(folder_hash).or_default(); let map = map.entry(folder_hash).or_default();
(*map).insert(hash, PathBuf::from(file)); (*map).insert(hash, PathBuf::from(file).into());
} }
let op = Box::new(MaildirOp::new( let op = Box::new(MaildirOp::new(
hash, hash,
@ -694,7 +731,7 @@ fn add_path_to_index(
{ {
let mut map = hash_index.lock().unwrap(); let mut map = hash_index.lock().unwrap();
let map = map.entry(folder_hash).or_default();; let map = map.entry(folder_hash).or_default();;
map.insert(hash, path.to_path_buf()); map.insert(hash, path.to_path_buf().into());
debug!( debug!(
"inserted {} in {} map, len={}", "inserted {} in {} map, len={}",
hash, hash,