From eff1c1641cbfd7d672d12bdfe7dde020c5cb267c Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 26 May 2019 02:25:30 +0300 Subject: melib: track modified paths in maildir Keep modified path status in maildir to prevent not-found panics --- melib/src/mailbox/backends/maildir.rs | 13 +++--- 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 @@ -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, +} + +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 for MaildirPath { + fn from(val: PathBuf) -> MaildirPath { + MaildirPath { + buf: val, + modified: None, + } + } +} + #[derive(Debug, Default)] pub struct HashIndex { - index: FnvHashMap, + index: FnvHashMap, hash: FolderHash, } impl Deref for HashIndex { - type Target = FnvHashMap; - fn deref(&self) -> &FnvHashMap { + type Target = FnvHashMap; + fn deref(&self) -> &FnvHashMap { &self.index } } impl DerefMut for HashIndex { - fn deref_mut(&mut self) -> &mut FnvHashMap { + fn deref_mut(&mut self) -> &mut FnvHashMap { &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, -- cgit v1.2.3