melib/backends: add collection() method to MailBackend
Keep track of the Collection state in the backend sidelazy_fetch
parent
eb8d29813c
commit
781a1d0e1b
|
@ -58,7 +58,7 @@ use self::maildir::MaildirType;
|
|||
use self::mbox::MboxType;
|
||||
use super::email::{Envelope, EnvelopeHash, Flag};
|
||||
use std::any::Any;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
|
@ -348,9 +348,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
|
|||
mailbox_hash: MailboxHash,
|
||||
) -> ResultFuture<()>;
|
||||
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
None
|
||||
}
|
||||
fn collection(&self) -> crate::Collection;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||
|
||||
|
|
|
@ -42,20 +42,21 @@ use crate::backends::{
|
|||
*,
|
||||
};
|
||||
|
||||
use crate::collection::Collection;
|
||||
use crate::conf::AccountSettings;
|
||||
use crate::connections::timeout;
|
||||
use crate::email::{parser::BytesExt, *};
|
||||
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
||||
use futures::lock::Mutex as FutureMutex;
|
||||
use futures::stream::Stream;
|
||||
use std::collections::{hash_map::DefaultHasher, BTreeMap};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
use std::hash::Hasher;
|
||||
use std::pin::Pin;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
pub type ImapNum = usize;
|
||||
|
@ -142,7 +143,7 @@ pub struct UIDStore {
|
|||
msn_index: Arc<Mutex<HashMap<MailboxHash, Vec<UID>>>>,
|
||||
|
||||
byte_cache: Arc<Mutex<HashMap<UID, EnvelopeCache>>>,
|
||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||
collection: Collection,
|
||||
|
||||
/* Offline caching */
|
||||
uidvalidity: Arc<Mutex<HashMap<MailboxHash, UID>>>,
|
||||
|
@ -178,7 +179,7 @@ impl UIDStore {
|
|||
msn_index: Default::default(),
|
||||
byte_cache: Default::default(),
|
||||
mailboxes: Arc::new(FutureMutex::new(Default::default())),
|
||||
tag_index: Arc::new(RwLock::new(Default::default())),
|
||||
collection: Default::default(),
|
||||
is_online: Arc::new(Mutex::new((
|
||||
SystemTime::now(),
|
||||
Err(MeliError::new("Account is uninitialised.")),
|
||||
|
@ -710,7 +711,7 @@ impl MailBackend for ImapType {
|
|||
/* Set flags/tags to true */
|
||||
let mut set_seen = false;
|
||||
let command = {
|
||||
let mut tag_lck = uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = uid_store.collection.tag_index.write().unwrap();
|
||||
let mut cmd = format!("UID STORE {}", uids[0]);
|
||||
for uid in uids.iter().skip(1) {
|
||||
cmd = format!("{},{}", cmd, uid);
|
||||
|
@ -859,10 +860,6 @@ impl MailBackend for ImapType {
|
|||
}))
|
||||
}
|
||||
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
Some(self.uid_store.tag_index.clone())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -871,6 +868,10 @@ impl MailBackend for ImapType {
|
|||
self
|
||||
}
|
||||
|
||||
fn collection(&self) -> Collection {
|
||||
self.uid_store.collection.clone()
|
||||
}
|
||||
|
||||
fn create_mailbox(
|
||||
&mut self,
|
||||
mut path: String,
|
||||
|
@ -1773,7 +1774,7 @@ async fn fetch_hlpr(state: &mut FetchState) -> Result<Vec<Envelope>> {
|
|||
}
|
||||
env.set_references(value);
|
||||
}
|
||||
let mut tag_lck = uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = uid_store.collection.tag_index.write().unwrap();
|
||||
if let Some((flags, keywords)) = flags {
|
||||
env.set_flags(*flags);
|
||||
if !env.is_seen() {
|
||||
|
|
|
@ -239,7 +239,7 @@ mod sqlite3_m {
|
|||
.entry(mailbox_hash)
|
||||
.and_modify(|entry| *entry = uidvalidity)
|
||||
.or_insert(uidvalidity);
|
||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||
for f in to_str!(&flags).split('\0') {
|
||||
let hash = tag_hash!(f);
|
||||
//debug!("hash {} flag {}", hash, &f);
|
||||
|
|
|
@ -171,7 +171,7 @@ impl ImapConnection {
|
|||
}
|
||||
env.set_references(value);
|
||||
}
|
||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||
if let Some((flags, keywords)) = flags {
|
||||
env.set_flags(*flags);
|
||||
if !env.is_seen() {
|
||||
|
@ -469,7 +469,7 @@ impl ImapConnection {
|
|||
}
|
||||
env.set_references(value);
|
||||
}
|
||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||
if let Some((flags, keywords)) = flags {
|
||||
env.set_flags(*flags);
|
||||
if !env.is_seen() {
|
||||
|
|
|
@ -238,7 +238,7 @@ impl ImapConnection {
|
|||
}
|
||||
env.set_references(value);
|
||||
}
|
||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||
if let Some((flags, keywords)) = flags {
|
||||
env.set_flags(*flags);
|
||||
if !env.is_seen() {
|
||||
|
@ -381,7 +381,7 @@ impl ImapConnection {
|
|||
}
|
||||
env.set_references(value);
|
||||
}
|
||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||
if let Some((flags, keywords)) = flags {
|
||||
env.set_flags(*flags);
|
||||
if !env.is_seen() {
|
||||
|
|
|
@ -388,7 +388,7 @@ pub async fn examine_updates(
|
|||
}
|
||||
env.set_references(value);
|
||||
}
|
||||
let mut tag_lck = uid_store.tag_index.write().unwrap();
|
||||
let mut tag_lck = uid_store.collection.tag_index.write().unwrap();
|
||||
if let Some((flags, keywords)) = flags {
|
||||
env.set_flags(*flags);
|
||||
if !env.is_seen() {
|
||||
|
|
|
@ -23,12 +23,13 @@ use crate::backends::*;
|
|||
use crate::conf::AccountSettings;
|
||||
use crate::email::*;
|
||||
use crate::error::{MeliError, Result};
|
||||
use crate::Collection;
|
||||
use futures::lock::Mutex as FutureMutex;
|
||||
use isahc::config::RedirectPolicy;
|
||||
use isahc::prelude::HttpClient;
|
||||
use isahc::ResponseExt;
|
||||
use serde_json::Value;
|
||||
use std::collections::{hash_map::DefaultHasher, BTreeMap, HashMap, HashSet};
|
||||
use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};
|
||||
use std::convert::TryFrom;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::str::FromStr;
|
||||
|
@ -183,7 +184,7 @@ pub struct Store {
|
|||
pub id_store: Arc<Mutex<HashMap<EnvelopeHash, Id<EmailObject>>>>,
|
||||
pub reverse_id_store: Arc<Mutex<HashMap<Id<EmailObject>, EnvelopeHash>>>,
|
||||
pub blob_id_store: Arc<Mutex<HashMap<EnvelopeHash, Id<BlobObject>>>>,
|
||||
pub tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||
pub collection: Collection,
|
||||
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, JmapMailbox>>>,
|
||||
pub mailboxes_index: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
||||
pub mailbox_state: Arc<Mutex<State<MailboxObject>>>,
|
||||
|
@ -194,7 +195,7 @@ pub struct Store {
|
|||
|
||||
impl Store {
|
||||
pub fn add_envelope(&self, obj: EmailObject) -> Envelope {
|
||||
let mut tag_lck = self.tag_index.write().unwrap();
|
||||
let mut tag_lck = self.collection.tag_index.write().unwrap();
|
||||
let tags = obj
|
||||
.keywords()
|
||||
.keys()
|
||||
|
@ -483,10 +484,6 @@ impl MailBackend for JmapType {
|
|||
}))
|
||||
}
|
||||
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
Some(self.store.tag_index.clone())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -495,6 +492,10 @@ impl MailBackend for JmapType {
|
|||
self
|
||||
}
|
||||
|
||||
fn collection(&self) -> Collection {
|
||||
self.store.collection.clone()
|
||||
}
|
||||
|
||||
fn search(
|
||||
&self,
|
||||
q: crate::search::Query,
|
||||
|
@ -753,7 +754,7 @@ impl MailBackend for JmapType {
|
|||
}
|
||||
|
||||
{
|
||||
let mut tag_index_lck = store.tag_index.write().unwrap();
|
||||
let mut tag_index_lck = store.collection.tag_index.write().unwrap();
|
||||
for (flag, value) in flags.iter() {
|
||||
match flag {
|
||||
Ok(_) => {}
|
||||
|
@ -841,12 +842,12 @@ impl JmapType {
|
|||
online_status,
|
||||
event_consumer,
|
||||
is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
|
||||
collection: Collection::default(),
|
||||
|
||||
byte_cache: Default::default(),
|
||||
id_store: Default::default(),
|
||||
reverse_id_store: Default::default(),
|
||||
blob_id_store: Default::default(),
|
||||
tag_index: Default::default(),
|
||||
mailboxes: Default::default(),
|
||||
mailboxes_index: Default::default(),
|
||||
mailbox_state: Default::default(),
|
||||
|
|
|
@ -25,6 +25,7 @@ use crate::conf::AccountSettings;
|
|||
use crate::email::{Envelope, EnvelopeHash, Flag};
|
||||
use crate::error::{ErrorKind, MeliError, Result};
|
||||
use crate::shellexpand::ShellExpandTrait;
|
||||
use crate::Collection;
|
||||
use futures::prelude::Stream;
|
||||
|
||||
extern crate notify;
|
||||
|
@ -109,6 +110,7 @@ pub struct MaildirType {
|
|||
mailbox_index: Arc<Mutex<HashMap<EnvelopeHash, MailboxHash>>>,
|
||||
hash_indexes: HashIndexes,
|
||||
event_consumer: BackendEventConsumer,
|
||||
collection: Collection,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
|
@ -1003,6 +1005,10 @@ impl MailBackend for MaildirType {
|
|||
}))
|
||||
}
|
||||
|
||||
fn collection(&self) -> Collection {
|
||||
self.collection.clone()
|
||||
}
|
||||
|
||||
fn create_mailbox(
|
||||
&mut self,
|
||||
new_path: String,
|
||||
|
@ -1236,6 +1242,7 @@ impl MaildirType {
|
|||
hash_indexes: Arc::new(Mutex::new(hash_indexes)),
|
||||
mailbox_index: Default::default(),
|
||||
event_consumer,
|
||||
collection: Default::default(),
|
||||
path: root_path,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
use crate::backends::*;
|
||||
use crate::collection::Collection;
|
||||
use crate::conf::AccountSettings;
|
||||
use crate::email::parser::BytesExt;
|
||||
use crate::email::*;
|
||||
|
@ -708,6 +709,7 @@ impl<'a> Iterator for MessageIterator<'a> {
|
|||
pub struct MboxType {
|
||||
account_name: String,
|
||||
path: PathBuf,
|
||||
collection: Collection,
|
||||
mailbox_index: Arc<Mutex<HashMap<EnvelopeHash, MailboxHash>>>,
|
||||
mailboxes: Arc<Mutex<HashMap<MailboxHash, MboxMailbox>>>,
|
||||
prefer_mbox_type: Option<MboxReader>,
|
||||
|
@ -1057,6 +1059,10 @@ impl MailBackend for MboxType {
|
|||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn collection(&self) -> Collection {
|
||||
self.collection.clone()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! get_conf_val {
|
||||
|
@ -1120,6 +1126,7 @@ impl MboxType {
|
|||
)))
|
||||
}
|
||||
},
|
||||
collection: Collection::default(),
|
||||
mailbox_index: Default::default(),
|
||||
mailboxes: Default::default(),
|
||||
};
|
||||
|
|
|
@ -32,18 +32,18 @@ pub use operations::*;
|
|||
mod connection;
|
||||
pub use connection::*;
|
||||
|
||||
use crate::backends::*;
|
||||
use crate::conf::AccountSettings;
|
||||
use crate::email::*;
|
||||
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
||||
use crate::{backends::*, Collection};
|
||||
use futures::lock::Mutex as FutureMutex;
|
||||
use futures::stream::Stream;
|
||||
use std::collections::{hash_map::DefaultHasher, BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::collections::{hash_map::DefaultHasher, BTreeSet, HashMap, HashSet};
|
||||
use std::future::Future;
|
||||
use std::hash::Hasher;
|
||||
use std::pin::Pin;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
pub type UID = usize;
|
||||
|
||||
|
@ -77,6 +77,7 @@ pub struct UIDStore {
|
|||
hash_index: Arc<Mutex<HashMap<EnvelopeHash, (UID, MailboxHash)>>>,
|
||||
uid_index: Arc<Mutex<HashMap<(MailboxHash, UID), EnvelopeHash>>>,
|
||||
|
||||
collection: Collection,
|
||||
mailboxes: Arc<FutureMutex<HashMap<MailboxHash, NntpMailbox>>>,
|
||||
is_online: Arc<Mutex<(Instant, Result<()>)>>,
|
||||
event_consumer: BackendEventConsumer,
|
||||
|
@ -97,6 +98,7 @@ impl UIDStore {
|
|||
hash_index: Default::default(),
|
||||
uid_index: Default::default(),
|
||||
mailboxes: Arc::new(FutureMutex::new(Default::default())),
|
||||
collection: Collection::new(),
|
||||
is_online: Arc::new(Mutex::new((
|
||||
Instant::now(),
|
||||
Err(MeliError::new("Account is uninitialised.")),
|
||||
|
@ -294,10 +296,6 @@ impl MailBackend for NntpType {
|
|||
Err(MeliError::new("NNTP doesn't support deletion."))
|
||||
}
|
||||
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -306,6 +304,10 @@ impl MailBackend for NntpType {
|
|||
self
|
||||
}
|
||||
|
||||
fn collection(&self) -> Collection {
|
||||
self.uid_store.collection.clone()
|
||||
}
|
||||
|
||||
fn create_mailbox(
|
||||
&mut self,
|
||||
_path: String,
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::backends::*;
|
||||
use crate::conf::AccountSettings;
|
||||
use crate::email::{Envelope, EnvelopeHash, Flag};
|
||||
use crate::error::{MeliError, Result};
|
||||
use crate::shellexpand::ShellExpandTrait;
|
||||
use crate::{backends::*, Collection};
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::{
|
||||
hash_map::{DefaultHasher, HashMap},
|
||||
|
@ -220,7 +220,7 @@ pub struct NotmuchDb {
|
|||
mailboxes: Arc<RwLock<HashMap<MailboxHash, NotmuchMailbox>>>,
|
||||
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
||||
mailbox_index: Arc<RwLock<HashMap<EnvelopeHash, SmallVec<[MailboxHash; 16]>>>>,
|
||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||
collection: Collection,
|
||||
path: PathBuf,
|
||||
account_name: Arc<String>,
|
||||
account_hash: AccountHash,
|
||||
|
@ -358,7 +358,7 @@ impl NotmuchDb {
|
|||
path,
|
||||
index: Arc::new(RwLock::new(Default::default())),
|
||||
mailbox_index: Arc::new(RwLock::new(Default::default())),
|
||||
tag_index: Arc::new(RwLock::new(Default::default())),
|
||||
collection: Collection::default(),
|
||||
|
||||
mailboxes: Arc::new(RwLock::new(mailboxes)),
|
||||
save_messages_to: None,
|
||||
|
@ -510,7 +510,7 @@ impl MailBackend for NotmuchDb {
|
|||
)?);
|
||||
let index = self.index.clone();
|
||||
let mailbox_index = self.mailbox_index.clone();
|
||||
let tag_index = self.tag_index.clone();
|
||||
let tag_index = self.collection.tag_index.clone();
|
||||
let mailboxes = self.mailboxes.clone();
|
||||
let v: Vec<CString>;
|
||||
{
|
||||
|
@ -561,7 +561,7 @@ impl MailBackend for NotmuchDb {
|
|||
let mailboxes = self.mailboxes.clone();
|
||||
let index = self.index.clone();
|
||||
let mailbox_index = self.mailbox_index.clone();
|
||||
let tag_index = self.tag_index.clone();
|
||||
let tag_index = self.collection.tag_index.clone();
|
||||
let event_consumer = self.event_consumer.clone();
|
||||
Ok(Box::pin(async move {
|
||||
let new_revision_uuid = database.get_revision_uuid();
|
||||
|
@ -586,13 +586,13 @@ impl MailBackend for NotmuchDb {
|
|||
use notify::{watcher, RecursiveMode, Watcher};
|
||||
|
||||
let account_hash = self.account_hash;
|
||||
let collection = self.collection.clone();
|
||||
let lib = self.lib.clone();
|
||||
let path = self.path.clone();
|
||||
let revision_uuid = self.revision_uuid.clone();
|
||||
let mailboxes = self.mailboxes.clone();
|
||||
let index = self.index.clone();
|
||||
let mailbox_index = self.mailbox_index.clone();
|
||||
let tag_index = self.tag_index.clone();
|
||||
let event_consumer = self.event_consumer.clone();
|
||||
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
|
@ -616,7 +616,7 @@ impl MailBackend for NotmuchDb {
|
|||
mailboxes.clone(),
|
||||
index.clone(),
|
||||
mailbox_index.clone(),
|
||||
tag_index.clone(),
|
||||
collection.tag_index.clone(),
|
||||
account_hash.clone(),
|
||||
event_consumer.clone(),
|
||||
new_revision_uuid,
|
||||
|
@ -651,7 +651,7 @@ impl MailBackend for NotmuchDb {
|
|||
hash,
|
||||
index: self.index.clone(),
|
||||
bytes: None,
|
||||
tag_index: self.tag_index.clone(),
|
||||
collection: self.collection.clone(),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -693,7 +693,7 @@ impl MailBackend for NotmuchDb {
|
|||
self.lib.clone(),
|
||||
true,
|
||||
)?;
|
||||
let tag_index = self.tag_index.clone();
|
||||
let collection = self.collection.clone();
|
||||
let index = self.index.clone();
|
||||
|
||||
Ok(Box::pin(async move {
|
||||
|
@ -781,7 +781,11 @@ impl MailBackend for NotmuchDb {
|
|||
for (f, v) in flags.iter() {
|
||||
if let (Err(tag), true) = (f, v) {
|
||||
let hash = tag_hash!(tag);
|
||||
tag_index.write().unwrap().insert(hash, tag.to_string());
|
||||
collection
|
||||
.tag_index
|
||||
.write()
|
||||
.unwrap()
|
||||
.insert(hash, tag.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -834,8 +838,8 @@ impl MailBackend for NotmuchDb {
|
|||
}))
|
||||
}
|
||||
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
Some(self.tag_index.clone())
|
||||
fn collection(&self) -> Collection {
|
||||
self.collection.clone()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
|
@ -851,7 +855,7 @@ impl MailBackend for NotmuchDb {
|
|||
struct NotmuchOp {
|
||||
hash: EnvelopeHash,
|
||||
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||
collection: Collection,
|
||||
database: Arc<DbConnection>,
|
||||
bytes: Option<Vec<u8>>,
|
||||
lib: Arc<libloading::Library>,
|
||||
|
|
|
@ -25,7 +25,7 @@ use smallvec::SmallVec;
|
|||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
|
||||
pub struct EnvelopeRef<'g> {
|
||||
guard: RwLockReadGuard<'g, HashMap<EnvelopeHash, Envelope>>,
|
||||
|
@ -64,8 +64,9 @@ pub struct Collection {
|
|||
pub envelopes: Arc<RwLock<HashMap<EnvelopeHash, Envelope>>>,
|
||||
pub message_id_index: Arc<RwLock<HashMap<Vec<u8>, EnvelopeHash>>>,
|
||||
pub threads: Arc<RwLock<HashMap<MailboxHash, Threads>>>,
|
||||
sent_mailbox: Arc<RwLock<Option<MailboxHash>>>,
|
||||
pub sent_mailbox: Arc<RwLock<Option<MailboxHash>>>,
|
||||
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
||||
pub tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||
}
|
||||
|
||||
impl Default for Collection {
|
||||
|
@ -115,6 +116,7 @@ impl Collection {
|
|||
|
||||
Collection {
|
||||
envelopes: Arc::new(RwLock::new(Default::default())),
|
||||
tag_index: Arc::new(RwLock::new(BTreeMap::default())),
|
||||
message_id_index,
|
||||
threads,
|
||||
mailboxes,
|
||||
|
|
|
@ -44,7 +44,6 @@ pub use iterators::*;
|
|||
use crate::text_processing::grapheme_clusters::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fmt;
|
||||
|
@ -131,7 +130,7 @@ macro_rules! make {
|
|||
e.parent = Some($p);
|
||||
});
|
||||
let old_group = std::mem::replace($threads.groups.entry(old_group_hash).or_default(), ThreadGroup::Node {
|
||||
parent: RefCell::new(parent_group_hash),
|
||||
parent: Arc::new(RwLock::new(parent_group_hash)),
|
||||
});
|
||||
$threads.thread_nodes.entry($c).and_modify(|e| {
|
||||
e.group = parent_group_hash;
|
||||
|
@ -292,7 +291,7 @@ pub struct Thread {
|
|||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub enum ThreadGroup {
|
||||
Root(Thread),
|
||||
Node { parent: RefCell<ThreadHash> },
|
||||
Node { parent: Arc<RwLock<ThreadHash>> },
|
||||
}
|
||||
|
||||
impl Default for ThreadGroup {
|
||||
|
@ -411,16 +410,16 @@ impl ThreadNode {
|
|||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Threads {
|
||||
pub thread_nodes: HashMap<ThreadNodeHash, ThreadNode>,
|
||||
root_set: RefCell<Vec<ThreadNodeHash>>,
|
||||
tree_index: RefCell<Vec<ThreadNodeHash>>,
|
||||
root_set: Arc<RwLock<Vec<ThreadNodeHash>>>,
|
||||
tree_index: Arc<RwLock<Vec<ThreadNodeHash>>>,
|
||||
pub groups: HashMap<ThreadHash, ThreadGroup>,
|
||||
|
||||
message_ids: HashMap<Vec<u8>, ThreadNodeHash>,
|
||||
pub message_ids_set: HashSet<Vec<u8>>,
|
||||
pub missing_message_ids: HashSet<Vec<u8>>,
|
||||
pub hash_set: HashSet<EnvelopeHash>,
|
||||
sort: RefCell<(SortField, SortOrder)>,
|
||||
subsort: RefCell<(SortField, SortOrder)>,
|
||||
sort: Arc<RwLock<(SortField, SortOrder)>>,
|
||||
subsort: Arc<RwLock<(SortField, SortOrder)>>,
|
||||
}
|
||||
|
||||
impl PartialEq for ThreadNode {
|
||||
|
@ -454,13 +453,13 @@ impl Threads {
|
|||
pub fn find_group(&self, h: ThreadHash) -> ThreadHash {
|
||||
let p = match self.groups[&h] {
|
||||
ThreadGroup::Root(_) => return h,
|
||||
ThreadGroup::Node { ref parent } => *parent.borrow(),
|
||||
ThreadGroup::Node { ref parent } => *parent.read().unwrap(),
|
||||
};
|
||||
|
||||
let parent_group = self.find_group(p);
|
||||
match self.groups[&h] {
|
||||
ThreadGroup::Node { ref parent } => {
|
||||
*parent.borrow_mut() = parent_group;
|
||||
*parent.write().unwrap() = parent_group;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -491,8 +490,8 @@ impl Threads {
|
|||
message_ids_set,
|
||||
missing_message_ids,
|
||||
hash_set,
|
||||
sort: RefCell::new((SortField::Date, SortOrder::Desc)),
|
||||
subsort: RefCell::new((SortField::Subject, SortOrder::Desc)),
|
||||
sort: Arc::new(RwLock::new((SortField::Date, SortOrder::Desc))),
|
||||
subsort: Arc::new(RwLock::new((SortField::Subject, SortOrder::Desc))),
|
||||
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -573,7 +572,7 @@ impl Threads {
|
|||
};
|
||||
|
||||
if self.thread_nodes[&t_id].parent.is_none() {
|
||||
let mut tree_index = self.tree_index.borrow_mut();
|
||||
let mut tree_index = self.tree_index.write().unwrap();
|
||||
if let Some(i) = tree_index.iter().position(|t| *t == t_id) {
|
||||
tree_index.remove(i);
|
||||
}
|
||||
|
@ -845,7 +844,7 @@ impl Threads {
|
|||
|
||||
/*
|
||||
save_graph(
|
||||
&self.tree_index.borrow(),
|
||||
&self.tree_index.read().unwrap(),
|
||||
&self.thread_nodes,
|
||||
&self
|
||||
.message_ids
|
||||
|
@ -871,7 +870,7 @@ impl Threads {
|
|||
ref thread_nodes,
|
||||
..
|
||||
} = self;
|
||||
let tree = &mut tree_index.borrow_mut();
|
||||
let tree = &mut tree_index.write().unwrap();
|
||||
for t in tree.iter_mut() {
|
||||
thread_nodes[t].children.sort_by(|a, b| match subsort {
|
||||
(SortField::Date, SortOrder::Desc) => {
|
||||
|
@ -1090,7 +1089,7 @@ impl Threads {
|
|||
});
|
||||
}
|
||||
fn inner_sort_by(&self, sort: (SortField, SortOrder), envelopes: &Envelopes) {
|
||||
let tree = &mut self.tree_index.borrow_mut();
|
||||
let tree = &mut self.tree_index.write().unwrap();
|
||||
let envelopes = envelopes.read().unwrap();
|
||||
tree.sort_by(|a, b| match sort {
|
||||
(SortField::Date, SortOrder::Desc) => {
|
||||
|
@ -1172,13 +1171,13 @@ impl Threads {
|
|||
subsort: (SortField, SortOrder),
|
||||
envelopes: &Envelopes,
|
||||
) {
|
||||
if *self.sort.borrow() != sort {
|
||||
if *self.sort.read().unwrap() != sort {
|
||||
self.inner_sort_by(sort, envelopes);
|
||||
*self.sort.borrow_mut() = sort;
|
||||
*self.sort.write().unwrap() = sort;
|
||||
}
|
||||
if *self.subsort.borrow() != subsort {
|
||||
if *self.subsort.read().unwrap() != subsort {
|
||||
self.inner_subsort_by(subsort, envelopes);
|
||||
*self.subsort.borrow_mut() = subsort;
|
||||
*self.subsort.write().unwrap() = subsort;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1196,11 +1195,11 @@ impl Threads {
|
|||
}
|
||||
|
||||
pub fn root_len(&self) -> usize {
|
||||
self.tree_index.borrow().len()
|
||||
self.tree_index.read().unwrap().len()
|
||||
}
|
||||
|
||||
pub fn root_set(&self, idx: usize) -> ThreadNodeHash {
|
||||
self.tree_index.borrow()[idx]
|
||||
self.tree_index.read().unwrap()[idx]
|
||||
}
|
||||
|
||||
pub fn roots(&self) -> SmallVec<[ThreadHash; 1024]> {
|
||||
|
|
|
@ -895,9 +895,9 @@ impl CompactListing {
|
|||
let thread = threads.thread_ref(hash);
|
||||
let mut tags = String::new();
|
||||
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
let account = &context.accounts[&self.cursor_pos.0];
|
||||
if account.backend_capabilities.supports_tags {
|
||||
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||
for t in e.labels().iter() {
|
||||
if mailbox_settings!(
|
||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||
|
|
|
@ -908,9 +908,9 @@ impl ConversationsListing {
|
|||
let thread = threads.thread_ref(hash);
|
||||
let mut tags = String::new();
|
||||
let mut colors = SmallVec::new();
|
||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
let account = &context.accounts[&self.cursor_pos.0];
|
||||
if account.backend_capabilities.supports_tags {
|
||||
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||
for t in e.labels().iter() {
|
||||
if mailbox_settings!(
|
||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||
|
|
|
@ -732,9 +732,9 @@ impl PlainListing {
|
|||
fn make_entry_string(&self, e: EnvelopeRef, context: &Context) -> EntryStrings {
|
||||
let mut tags = String::new();
|
||||
let mut colors = SmallVec::new();
|
||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
let account = &context.accounts[&self.cursor_pos.0];
|
||||
if account.backend_capabilities.supports_tags {
|
||||
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||
for t in e.labels().iter() {
|
||||
if mailbox_settings!(
|
||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||
|
|
|
@ -839,9 +839,9 @@ impl ThreadListing {
|
|||
fn make_entry_string(&self, e: &Envelope, context: &Context) -> EntryStrings {
|
||||
let mut tags = String::new();
|
||||
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
let account = &context.accounts[&self.cursor_pos.0];
|
||||
if account.backend_capabilities.supports_tags {
|
||||
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||
for t in e.labels().iter() {
|
||||
if mailbox_settings!(
|
||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||
|
|
|
@ -517,7 +517,7 @@ impl Account {
|
|||
tree: Default::default(),
|
||||
address_book,
|
||||
sent_mailbox: Default::default(),
|
||||
collection: Default::default(),
|
||||
collection: backend.collection(),
|
||||
settings,
|
||||
sender,
|
||||
job_executor,
|
||||
|
|
|
@ -46,7 +46,7 @@ pub struct PluginBackend {
|
|||
plugin: Plugin,
|
||||
child: std::process::Child,
|
||||
channel: Arc<Mutex<RpcChannel>>,
|
||||
tag_index: Option<Arc<RwLock<BTreeMap<u64, String>>>>,
|
||||
collection: melib::Collection,
|
||||
is_online: Arc<Mutex<(std::time::Instant, Result<()>)>>,
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,6 @@ impl MailBackend for PluginBackend {
|
|||
Ok(Box::new(PluginOp {
|
||||
hash,
|
||||
channel: self.channel.clone(),
|
||||
tag_index: self.tag_index.clone(),
|
||||
bytes: None,
|
||||
}))
|
||||
}
|
||||
|
@ -219,8 +218,8 @@ impl MailBackend for PluginBackend {
|
|||
) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
|
||||
Err(MeliError::new("Unimplemented."))
|
||||
}
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
self.tag_index.clone()
|
||||
fn collection(&self) -> melib::Collection {
|
||||
self.collection.clone()
|
||||
}
|
||||
fn as_any(&self) -> &dyn ::std::any::Any {
|
||||
self
|
||||
|
@ -257,7 +256,7 @@ impl PluginBackend {
|
|||
child,
|
||||
plugin,
|
||||
channel: Arc::new(Mutex::new(channel)),
|
||||
tag_index: None,
|
||||
collection: Default::default(),
|
||||
is_online: Arc::new(Mutex::new((now, Err(MeliError::new("Unitialized"))))),
|
||||
}))
|
||||
}
|
||||
|
@ -285,7 +284,6 @@ impl PluginBackend {
|
|||
struct PluginOp {
|
||||
hash: EnvelopeHash,
|
||||
channel: Arc<Mutex<RpcChannel>>,
|
||||
tag_index: Option<Arc<RwLock<BTreeMap<u64, String>>>>,
|
||||
bytes: Option<String>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue