commit 1bf2c1c01aa885f49ef2e9886f8c1af9c5aaf309
parent 1b2dbdf073cc042075ffd377564a71e7089e825d
Author: Edward Z. Yang <ezyang@mit.edu>
Date: Mon, 27 Aug 2012 13:31:12 -0400
Better backwards synchronization for killed messages.
Signed-off-by: Edward Z. Yang
Diffstat:
4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/bin/sup-sync-back-maildir b/bin/sup-sync-back-maildir
@@ -88,6 +88,10 @@ begin
m.merge_labels_from_locations [:replied, :forwarded]
end
+ if Redwood::Index.message_joining_killed? m
+ m.labels += [:killed]
+ end
+
index.save_message m
end
end
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
@@ -161,6 +161,32 @@ EOS
matchset.matches_estimated
end
+ ## check if a message is part of a killed thread
+ ## (warning: duplicates code below)
+ ## NOTE: We can be more efficient if we assume every
+ ## killed message that hasn't been initially added
+ ## to the indexi s this way
+ def message_joining_killed? m
+ return false unless doc = find_doc(m.id)
+ queue = doc.value(THREAD_VALUENO).split(',')
+ seen_threads = Set.new
+ seen_messages = Set.new [m.id]
+ while not queue.empty?
+ thread_id = queue.pop
+ next if seen_threads.member? thread_id
+ return true if thread_killed?(thread_id)
+ seen_threads << thread_id
+ docs = term_docids(mkterm(:thread, thread_id)).map { |x| @xapian.document x }
+ docs.each do |doc|
+ msgid = doc.value MSGID_VALUENO
+ next if seen_messages.member? msgid
+ seen_messages << msgid
+ queue.concat doc.value(THREAD_VALUENO).split(',')
+ end
+ end
+ false
+ end
+
## yield all messages in the thread containing 'm' by repeatedly
## querying the index. yields pairs of message ids and
## message-building lambdas, so that building an unwanted message
diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
@@ -214,7 +214,7 @@ private
if labels.member? :forwarded then new_flags.add?( "P" ) else new_flags.delete?( "P" ) end
if labels.member? :replied then new_flags.add?( "R" ) else new_flags.delete?( "R" ) end
if not labels.member? :unread then new_flags.add?( "S" ) else new_flags.delete?( "S" ) end
- if labels.member? :deleted then new_flags.add?( "T" ) else new_flags.delete?( "T" ) end
+ if labels.member? :deleted or labels.member? :killed then new_flags.add?( "T" ) else new_flags.delete?( "T" ) end
## Flags must be stored in ASCII order according to Maildir
## documentation
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
@@ -188,6 +188,11 @@ EOS
yield :add, m, old_m, args[:progress] if block_given?
Index.sync_message m, true
+ if Index.message_joining_killed? m
+ m.labels += [:killed]
+ Index.sync_message m, true
+ end
+
## We need to add or unhide the message when it either did not exist
## before at all or when it was updated. We do *not* add/unhide when
## the same message was found at a different location