From d926cadc4d5b3bd613354976afd74ab3adb7d5df Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 3 Nov 2019 13:12:28 +0200 Subject: [PATCH] melib: remove argument from MailBackend operation() The operation() method on the MailBackend trait returns a trait object that can read or modify an Envelope directly from the backend. This is used to get eg the envelope's text, or set flags. It has two arguments, envelope hash and folder hash. Only the Maildir backend needed the latter argument, and it can be replaced with a dictionary to match envelope hashes to folder hashes within the Maildir backend. --- melib/src/backends.rs | 4 ++-- melib/src/backends/imap.rs | 2 +- melib/src/backends/maildir/backend.rs | 28 ++++++++++++++++++++++++--- melib/src/backends/mbox.rs | 2 +- ui/src/conf/accounts.rs | 23 +++++----------------- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/melib/src/backends.rs b/melib/src/backends.rs index f1841a0b3..1649bad21 100644 --- a/melib/src/backends.rs +++ b/melib/src/backends.rs @@ -176,7 +176,7 @@ pub enum FolderOperation { type NewFolderName = String; -pub trait MailBackend: ::std::fmt::Debug { +pub trait MailBackend: ::std::fmt::Debug + Send + Sync { fn is_online(&self) -> bool; fn get(&mut self, folder: &Folder) -> Async>>; fn watch( @@ -185,7 +185,7 @@ pub trait MailBackend: ::std::fmt::Debug { work_context: WorkContext, ) -> Result; fn folders(&self) -> FnvHashMap; - fn operation(&self, hash: EnvelopeHash, folder_hash: FolderHash) -> Box; + fn operation(&self, hash: EnvelopeHash) -> Box; fn save(&self, bytes: &[u8], folder: &str, flags: Option) -> Result<()>; fn folder_operation(&mut self, _path: &str, _op: FolderOperation) -> Result<()> { diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs index adcb151c5..96addca33 100644 --- a/melib/src/backends/imap.rs +++ b/melib/src/backends/imap.rs @@ -259,7 +259,7 @@ impl MailBackend for ImapType { .collect() } - fn operation(&self, hash: EnvelopeHash, _folder_hash: FolderHash) -> Box { + fn operation(&self, hash: EnvelopeHash) -> Box { let (uid, folder_hash) = self.hash_index.lock().unwrap()[&hash]; Box::new(ImapOp::new( uid, diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs index f6b4af18a..75a20aa35 100644 --- a/melib/src/backends/maildir/backend.rs +++ b/melib/src/backends/maildir/backend.rs @@ -114,7 +114,7 @@ pub type HashIndexes = Arc>>; pub struct MaildirType { name: String, folders: FnvHashMap, - //folder_index: FnvHashMap, + folder_index: Arc>>, hash_indexes: HashIndexes, path: PathBuf, } @@ -207,6 +207,7 @@ impl MailBackend for MaildirType { let cache_dir = xdg::BaseDirectories::with_profile("meli", &self.name).unwrap(); debug!("watching {:?}", root_path); let hash_indexes = self.hash_indexes.clone(); + let folder_index = self.folder_index.clone(); let handle = thread::Builder::new() .name("folder watch".to_string()) .spawn(move || { @@ -255,6 +256,7 @@ impl MailBackend for MaildirType { &cache_dir, file_name, ) { + folder_index.lock().unwrap().insert(env.hash(),folder_hash); debug!( "Create event {} {} {}", env.hash(), @@ -300,6 +302,7 @@ impl MailBackend for MaildirType { &cache_dir, file_name, ) { + folder_index.lock().unwrap().insert(env.hash(),folder_hash); sender.send(RefreshEvent { hash: folder_hash, kind: Create(Box::new(env)), @@ -398,6 +401,7 @@ impl MailBackend for MaildirType { hash: get_path_hash!(dest), kind: Rename(old_hash, new_hash), }); + folder_index.lock().unwrap().insert(new_hash,get_path_hash!(dest) ); index_lock.insert(new_hash, dest.into()); continue; } else if !index_lock.contains_key(&new_hash) @@ -434,6 +438,7 @@ impl MailBackend for MaildirType { &cache_dir, file_name, ) { + folder_index.lock().unwrap().insert(env.hash(),folder_hash); debug!( "Create event {} {} {}", env.hash(), @@ -477,8 +482,12 @@ impl MailBackend for MaildirType { Ok(handle.thread().id()) } - fn operation(&self, hash: EnvelopeHash, folder_hash: FolderHash) -> Box { - Box::new(MaildirOp::new(hash, self.hash_indexes.clone(), folder_hash)) + fn operation(&self, hash: EnvelopeHash) -> Box { + Box::new(MaildirOp::new( + hash, + self.hash_indexes.clone(), + self.folder_index.lock().unwrap()[&hash], + )) } fn save(&self, bytes: &[u8], folder: &str, flags: Option) -> Result<()> { @@ -663,6 +672,7 @@ impl MaildirType { name: settings.name().to_string(), folders, hash_indexes, + folder_index: Default::default(), path: root_path, } } @@ -689,6 +699,7 @@ impl MaildirType { let name = format!("parsing {:?}", folder.name()); let root_path = self.path.to_path_buf(); let map = self.hash_indexes.clone(); + let folder_index = self.folder_index.clone(); let closure = move |work_context: crate::async_workers::WorkContext| { let name = name.clone(); @@ -698,6 +709,7 @@ impl MaildirType { .unwrap(); let root_path = root_path.clone(); let map = map.clone(); + let folder_index = folder_index.clone(); let tx = tx.clone(); let cache_dir = cache_dir.clone(); let path = path.clone(); @@ -737,6 +749,7 @@ impl MaildirType { let cache_dir = cache_dir.clone(); let tx = tx.clone(); let map = map.clone(); + let folder_index = folder_index.clone(); let root_path = root_path.clone(); let s = scope.builder().name(name.clone()).spawn(move |_| { let len = chunk.len(); @@ -746,6 +759,7 @@ impl MaildirType { for c in chunk.chunks(size) { //thread::yield_now(); let map = map.clone(); + let folder_index = folder_index.clone(); let len = c.len(); for file in c { /* Check if we have a cache file with this email's @@ -768,6 +782,10 @@ impl MaildirType { let map = map.entry(folder_hash).or_default(); let hash = env.hash(); map.insert(hash, file.clone().into()); + folder_index + .lock() + .unwrap() + .insert(hash, folder_hash); local_r.push(env); continue; } @@ -784,6 +802,10 @@ impl MaildirType { folder_hash, )); if let Some(e) = Envelope::from_token(op, hash) { + folder_index + .lock() + .unwrap() + .insert(e.hash(), folder_hash); if let Ok(cached) = cache_dir.place_cache_file(file_name) { diff --git a/melib/src/backends/mbox.rs b/melib/src/backends/mbox.rs index 327c3eb4e..06d78df62 100644 --- a/melib/src/backends/mbox.rs +++ b/melib/src/backends/mbox.rs @@ -537,7 +537,7 @@ impl MailBackend for MboxType { .map(|(h, f)| (*h, f.clone() as Folder)) .collect() } - fn operation(&self, hash: EnvelopeHash, _folder_hash: FolderHash) -> Box { + fn operation(&self, hash: EnvelopeHash) -> Box { let (offset, length) = { let index = self.index.lock().unwrap(); index[&hash] diff --git a/ui/src/conf/accounts.rs b/ui/src/conf/accounts.rs index 55ae3d6fa..d5ce32bbf 100644 --- a/ui/src/conf/accounts.rs +++ b/ui/src/conf/accounts.rs @@ -740,25 +740,12 @@ impl Account { self.collection.contains_key(&h) } pub fn operation(&self, h: EnvelopeHash) -> Box { - for mailbox in self.folders.values() { - match mailbox { - MailboxEntry::Available(ref m) | MailboxEntry::Parsing(ref m, _, _) => { - if m.envelopes.contains(&h) { - let operation = self.backend.operation(h, m.folder.hash()); - if self.settings.account.read_only() { - return ReadOnlyOp::new(operation); - } else { - return operation; - } - } - } - _ => {} - } + let operation = self.backend.operation(h); + if self.settings.account.read_only() { + ReadOnlyOp::new(operation) + } else { + operation } - debug!("didn't find {}", h); - debug!(&self.folders); - //debug!(&self.collection.envelopes); - unreachable!() } pub fn thread(&self, h: ThreadHash, f: FolderHash) -> &ThreadNode {