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);
}
}
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");
let old_hash = envelope.hash();
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 mut map = hash_index.lock().unwrap();
let map = map.entry(self.folder_hash).or_default();
map.insert(old_hash, new_name.clone());
map.insert(new_hash, new_name);
if let maildir_path = map.entry(old_hash).or_default() {
maildir_path.modified = Some(new_name.clone().into());
}
Ok(())
}
}

View File

@ -48,21 +48,49 @@ use std::result;
use std::sync::{Arc, Mutex};
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)]
pub struct HashIndex {
index: FnvHashMap<EnvelopeHash, PathBuf>,
index: FnvHashMap<EnvelopeHash, MaildirPath>,
hash: FolderHash,
}
impl Deref for HashIndex {
type Target = FnvHashMap<EnvelopeHash, PathBuf>;
fn deref(&self) -> &FnvHashMap<EnvelopeHash, PathBuf> {
type Target = FnvHashMap<EnvelopeHash, MaildirPath>;
fn deref(&self) -> &FnvHashMap<EnvelopeHash, MaildirPath> {
&self.index
}
}
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
}
}
@ -227,10 +255,10 @@ impl MailBackend for MaildirType {
/* Linear search in hash_index to find old hash */
let old_hash: EnvelopeHash = {
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?
*v = pathbuf.clone();
*v = pathbuf.clone().into();
*k
} else {
/* 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",
new_hash, &pathbuf
);
index_lock.insert(new_hash, pathbuf);
index_lock.insert(new_hash, pathbuf.into());
/* Send Write notice */
@ -288,13 +316,22 @@ impl MailBackend for MaildirType {
let mut hash_indexes_lock = hash_indexes.lock().unwrap();
let index_lock = hash_indexes_lock.entry(folder_hash).or_default();
let hash: EnvelopeHash = if let Some((k, _)) =
index_lock.iter().find(|(_, v)| **v == pathbuf)
index_lock.iter().find(|(_, v)| *v.buf == pathbuf)
{
*k
} else {
debug!("removed but not contained in index");
continue;
};
if let Some(path) = &index_lock[&hash].modified {
debug!(
"envelope {} has modified path set {}",
hash,
path.display()
);
continue;
}
index_lock.remove(&hash);
sender.send(RefreshEvent {
@ -322,7 +359,7 @@ impl MailBackend for MaildirType {
kind: Rename(old_hash, new_hash),
});
index_lock.remove(&old_hash);
index_lock.insert(new_hash, dest);
index_lock.insert(new_hash, dest.into());
continue;
} else if !index_lock.contains_key(&new_hash) {
debug!("not contains_new_key");
@ -618,7 +655,7 @@ impl MaildirType {
let mut map = map.lock().unwrap();
let map = map.entry(folder_hash).or_default();
let hash = env.hash();
map.insert(hash, file.clone());
map.insert(hash, file.clone().into());
local_r.push(env);
continue;
}
@ -627,7 +664,7 @@ impl MaildirType {
{
let mut map = map.lock().unwrap();
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(
hash,
@ -694,7 +731,7 @@ fn add_path_to_index(
{
let mut map = hash_index.lock().unwrap();
let map = map.entry(folder_hash).or_default();;
map.insert(hash, path.to_path_buf());
map.insert(hash, path.to_path_buf().into());
debug!(
"inserted {} in {} map, len={}",
hash,