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.
jmap
Manos Pitsidianakis 2019-11-03 13:12:28 +02:00
parent 0a606a71d1
commit d926cadc4d
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
5 changed files with 34 additions and 25 deletions

View File

@ -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<Result<Vec<Envelope>>>;
fn watch(
@ -185,7 +185,7 @@ pub trait MailBackend: ::std::fmt::Debug {
work_context: WorkContext,
) -> Result<std::thread::ThreadId>;
fn folders(&self) -> FnvHashMap<FolderHash, Folder>;
fn operation(&self, hash: EnvelopeHash, folder_hash: FolderHash) -> Box<dyn BackendOp>;
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp>;
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()>;
fn folder_operation(&mut self, _path: &str, _op: FolderOperation) -> Result<()> {

View File

@ -259,7 +259,7 @@ impl MailBackend for ImapType {
.collect()
}
fn operation(&self, hash: EnvelopeHash, _folder_hash: FolderHash) -> Box<dyn BackendOp> {
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
let (uid, folder_hash) = self.hash_index.lock().unwrap()[&hash];
Box::new(ImapOp::new(
uid,

View File

@ -114,7 +114,7 @@ pub type HashIndexes = Arc<Mutex<FnvHashMap<FolderHash, HashIndex>>>;
pub struct MaildirType {
name: String,
folders: FnvHashMap<FolderHash, MaildirFolder>,
//folder_index: FnvHashMap<FolderHash, usize>,
folder_index: Arc<Mutex<FnvHashMap<EnvelopeHash, FolderHash>>>,
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<dyn BackendOp> {
Box::new(MaildirOp::new(hash, self.hash_indexes.clone(), folder_hash))
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
Box::new(MaildirOp::new(
hash,
self.hash_indexes.clone(),
self.folder_index.lock().unwrap()[&hash],
))
}
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> 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)
{

View File

@ -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<dyn BackendOp> {
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
let (offset, length) = {
let index = self.index.lock().unwrap();
index[&hash]

View File

@ -740,25 +740,12 @@ impl Account {
self.collection.contains_key(&h)
}
pub fn operation(&self, h: EnvelopeHash) -> Box<dyn BackendOp> {
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 {