diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-05-26 02:25:30 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2019-06-10 19:40:50 +0300 |
commit | eff1c1641cbfd7d672d12bdfe7dde020c5cb267c (patch) | |
tree | ee78d29606240cf0aefa0cd675142e3c863d1c0c | |
parent | d8651db93ab76e442b35372edf592287d13c7259 (diff) |
melib: track modified paths in maildir
Keep modified path status in maildir to prevent not-found panics
-rw-r--r-- | melib/src/mailbox/backends/maildir.rs | 13 | ||||
-rw-r--r-- | melib/src/mailbox/backends/maildir/backend.rs | 61 |
2 files changed, 57 insertions, 17 deletions
diff --git a/melib/src/mailbox/backends/maildir.rs b/melib/src/mailbox/backends/maildir.rs index 4f7f0e2c..e9c0b9af 100644 --- a/melib/src/mailbox/backends/maildir.rs +++ b/melib/src/mailbox/backends/maildir.rs @@ -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(()) } } diff --git a/melib/src/mailbox/backends/maildir/backend.rs b/melib/src/mailbox/backends/maildir/backend.rs index af9ba546..c1a99b28 100644 --- a/melib/src/mailbox/backends/maildir/backend.rs +++ b/melib/src/mailbox/backends/maildir/backend.rs @@ -49,20 +49,48 @@ 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, |