Keep 2 indexes by UID to determine flag changes; fix #7338
Previously, the EmailIdentifier key's hash value was sometimes changing during the execution of the function, so when someone later went to look up the flags, the hash map was returning NULL. This way we delay hashing the EmailIdentifier till right before it's used, so its hash value can't change.
This commit is contained in:
parent
4794702ead
commit
93ae747f3c
1 changed files with 19 additions and 5 deletions
|
|
@ -176,8 +176,9 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
|
|||
Gee.Collection<Geary.EmailIdentifier> all_appended_ids = new Gee.ArrayList<Geary.EmailIdentifier>();
|
||||
Gee.Collection<Geary.EmailIdentifier> all_locally_appended_ids = new Gee.ArrayList<Geary.EmailIdentifier>();
|
||||
Gee.Collection<Geary.EmailIdentifier> all_removed_ids = new Gee.ArrayList<Geary.EmailIdentifier>();
|
||||
Gee.Map<Geary.EmailIdentifier, Geary.EmailFlags> all_flags_changed = new Gee.HashMap<Geary.EmailIdentifier,
|
||||
Geary.EmailFlags>();
|
||||
Gee.Map<Imap.UID, Geary.EmailFlags> all_flags_changed = new Gee.HashMap<Imap.UID, Geary.EmailFlags>();
|
||||
Gee.Map<Imap.UID, Geary.EmailIdentifier> uid_to_email_id_map
|
||||
= new Gee.HashMap<Imap.UID, Geary.EmailIdentifier>();
|
||||
|
||||
// to match all flags and find all removed interior to the local store's vector of messages, start from
|
||||
// local earliest message and work upwards
|
||||
|
|
@ -284,7 +285,15 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
|
|||
if (replay_queue.query_local_writebehind_operation(ReplayOperation.WritebehindOperation.UPDATE_FLAGS,
|
||||
remote_email.id, (Imap.EmailFlags) remote_email.email_flags)) {
|
||||
to_create_or_merge.add(remote_email);
|
||||
all_flags_changed.set(remote_email.id, remote_email.email_flags);
|
||||
|
||||
// We can't keep a map of EmailId => flags, because sometimes the EmailId
|
||||
// changes its hash value (see ImapDB.EmailIdentifier.promote_with_message_id).
|
||||
// Instead, we index by UID (which doesn't change during this function), and
|
||||
// rebuild the map of EmailId => flags later.
|
||||
all_flags_changed.set(((ImapDB.EmailIdentifier) remote_email.id).uid,
|
||||
remote_email.email_flags);
|
||||
uid_to_email_id_map.set(((ImapDB.EmailIdentifier) remote_email.id).uid,
|
||||
remote_email.id);
|
||||
|
||||
Logging.debug(Logging.Flag.FOLDER_NORMALIZATION, "%s: merging remote ID %s",
|
||||
to_string(), remote_email.id.to_string());
|
||||
|
|
@ -454,8 +463,13 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
|
|||
|
||||
// notify flag changes
|
||||
if (all_flags_changed.size > 0) {
|
||||
debug("Notifying of %d changed flags since %s last seen", all_flags_changed.size, to_string());
|
||||
notify_email_flags_changed(all_flags_changed);
|
||||
Gee.Map<Geary.EmailIdentifier, Geary.EmailFlags> changed_flags
|
||||
= new Gee.HashMap<Geary.EmailIdentifier, Geary.EmailFlags>();
|
||||
foreach (Imap.UID uid in all_flags_changed.keys)
|
||||
changed_flags.set(uid_to_email_id_map.get(uid), all_flags_changed.get(uid));
|
||||
|
||||
debug("Notifying of %d changed flags since %s last seen", changed_flags.size, to_string());
|
||||
notify_email_flags_changed(changed_flags);
|
||||
}
|
||||
|
||||
debug("Completed normalize_folder %s", to_string());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue