summaryrefslogtreecommitdiffstats
path: root/melib/src
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-06-11 11:41:08 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-06-11 11:41:08 +0300
commit2d3f49d64d2f4fc28efc4c2786679e3d0be88ace (patch)
tree5e1de430d4369c8fec2291eff17a024f41d9efcf /melib/src
parent55948dd7c231eece036688f1b370073161053a15 (diff)
imap: index by (MailboxHash, UID) instead of just UID
Mailboxes can share UIDs.
Diffstat (limited to 'melib/src')
-rw-r--r--melib/src/backends/imap.rs16
-rw-r--r--melib/src/backends/imap/untagged.rs27
-rw-r--r--melib/src/backends/imap/watch.rs51
3 files changed, 75 insertions, 19 deletions
diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs
index e3d75f6c..abb73000 100644
--- a/melib/src/backends/imap.rs
+++ b/melib/src/backends/imap.rs
@@ -126,7 +126,7 @@ pub struct UIDStore {
cache_headers: bool,
uidvalidity: Arc<Mutex<HashMap<MailboxHash, UID>>>,
hash_index: Arc<Mutex<HashMap<EnvelopeHash, (UID, MailboxHash)>>>,
- uid_index: Arc<Mutex<HashMap<UID, EnvelopeHash>>>,
+ uid_index: Arc<Mutex<HashMap<(MailboxHash, UID), EnvelopeHash>>>,
byte_cache: Arc<Mutex<HashMap<UID, EnvelopeCache>>>,
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
@@ -264,7 +264,11 @@ impl MailBackend for ImapType {
.lock()
.unwrap()
.insert(env.hash(), (uid, mailbox_hash));
- uid_store.uid_index.lock().unwrap().insert(uid, env.hash());
+ uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .insert((mailbox_hash, uid), env.hash());
payload.push(env);
}
debug!("sending cached payload for {}", mailbox_hash);
@@ -378,7 +382,11 @@ impl MailBackend for ImapType {
.lock()
.unwrap()
.insert(env.hash(), (uid, mailbox_hash));
- uid_store.uid_index.lock().unwrap().insert(uid, env.hash());
+ uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .insert((mailbox_hash, uid), env.hash());
envelopes.push((uid, env));
}
exists =
@@ -924,7 +932,7 @@ impl MailBackend for ImapType {
.split_whitespace()
.map(usize::from_str)
.filter_map(std::result::Result::ok)
- .filter_map(|uid| uid_index.get(&uid))
+ .filter_map(|uid| uid_index.get(&(mailbox_hash, uid)))
.map(|env_hash_ref| *env_hash_ref),
));
}
diff --git a/melib/src/backends/imap/untagged.rs b/melib/src/backends/imap/untagged.rs
index 30c5dad2..52646936 100644
--- a/melib/src/backends/imap/untagged.rs
+++ b/melib/src/backends/imap/untagged.rs
@@ -100,7 +100,13 @@ impl ImapConnection {
uid, flags, body, ..
} in v
{
- if self.uid_store.uid_index.lock().unwrap().contains_key(&uid) {
+ if self
+ .uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .contains_key(&(mailbox_hash, uid))
+ {
continue 'fetch_responses;
}
if let Ok(mut env) = Envelope::from_bytes(
@@ -116,7 +122,7 @@ impl ImapConnection {
.uid_index
.lock()
.unwrap()
- .insert(uid, env.hash());
+ .insert((mailbox_hash, uid), env.hash());
if let Some((_, keywords)) = flags {
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
for f in keywords {
@@ -185,7 +191,12 @@ impl ImapConnection {
} in v
{
*mailbox.exists.lock().unwrap() += 1;
- if !self.uid_store.uid_index.lock().unwrap().contains_key(&uid)
+ if !self
+ .uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .contains_key(&(mailbox_hash, uid))
{
if let Ok(mut env) = Envelope::from_bytes(
body.unwrap(),
@@ -200,7 +211,7 @@ impl ImapConnection {
.uid_index
.lock()
.unwrap()
- .insert(uid, env.hash());
+ .insert((mailbox_hash, uid), env.hash());
debug!(
"Create event {} {} {}",
env.hash(),
@@ -271,8 +282,12 @@ impl ImapConnection {
{
Ok(mut v) => {
if let Some(uid) = v.pop() {
- if let Some(env_hash) =
- self.uid_store.uid_index.lock().unwrap().get(&uid)
+ if let Some(env_hash) = self
+ .uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .get(&(mailbox_hash, uid))
{
self.uid_store
.refresh_events
diff --git a/melib/src/backends/imap/watch.rs b/melib/src/backends/imap/watch.rs
index d4dcf4ea..2cacb6e2 100644
--- a/melib/src/backends/imap/watch.rs
+++ b/melib/src/backends/imap/watch.rs
@@ -331,7 +331,12 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> {
.unwrap();
ctr += 1;
*mailbox.exists.lock().unwrap() += 1;
- if !uid_store.uid_index.lock().unwrap().contains_key(&uid) {
+ if !uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .contains_key(&(mailbox_hash, uid))
+ {
if let Ok(mut env) = Envelope::from_bytes(
body.unwrap(),
flags.as_ref().map(|&(f, _)| f),
@@ -345,7 +350,7 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> {
.uid_index
.lock()
.unwrap()
- .insert(uid, env.hash());
+ .insert((mailbox_hash, uid), env.hash());
debug!(
"Create event {} {} {}",
env.hash(),
@@ -460,7 +465,12 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> {
format!("parsing {}/{} envelopes..", ctr, len),
))
.unwrap();
- if uid_store.uid_index.lock().unwrap().contains_key(&uid) {
+ if uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .contains_key(&(mailbox_hash, uid))
+ {
ctr += 1;
continue 'fetch_responses_b;
}
@@ -474,7 +484,11 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> {
.lock()
.unwrap()
.insert(env.hash(), (uid, mailbox_hash));
- uid_store.uid_index.lock().unwrap().insert(uid, env.hash());
+ uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .insert((mailbox_hash, uid), env.hash());
if let Some((_, keywords)) = flags {
let mut tag_lck = uid_store.tag_index.write().unwrap();
for f in keywords {
@@ -552,7 +566,12 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> {
{
Ok(mut v) => {
if let Some(uid) = v.pop() {
- if let Some(env_hash) = uid_store.uid_index.lock().unwrap().get(&uid) {
+ if let Some(env_hash) = uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .get(&(mailbox_hash, uid))
+ {
conn.add_refresh_event(RefreshEvent {
account_hash,
mailbox_hash,
@@ -696,7 +715,12 @@ pub fn examine_updates(
..
} in v
{
- if uid_store.uid_index.lock().unwrap().contains_key(&uid) {
+ if uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .contains_key(&(mailbox_hash, uid))
+ {
continue 'fetch_responses_c;
}
if let Ok(mut env) = Envelope::from_bytes(
@@ -712,7 +736,7 @@ pub fn examine_updates(
.uid_index
.lock()
.unwrap()
- .insert(uid, env.hash());
+ .insert((mailbox_hash, uid), env.hash());
debug!(
"Create event {} {} {}",
env.hash(),
@@ -790,7 +814,12 @@ pub fn examine_updates(
uid, flags, body, ..
} in v
{
- if uid_store.uid_index.lock().unwrap().contains_key(&uid) {
+ if uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .contains_key(&(mailbox_hash, uid))
+ {
continue 'fetch_responses_a;
}
if let Ok(mut env) =
@@ -801,7 +830,11 @@ pub fn examine_updates(
.lock()
.unwrap()
.insert(env.hash(), (uid, mailbox_hash));
- uid_store.uid_index.lock().unwrap().insert(uid, env.hash());
+ uid_store
+ .uid_index
+ .lock()
+ .unwrap()
+ .insert((mailbox_hash, uid), env.hash());
if let Some((_, keywords)) = flags {
let mut tag_lck = uid_store.tag_index.write().unwrap();
for f in keywords {