Changeset 697
- Timestamp:
- 08/30/10 23:01:34 (21 months ago)
- Location:
- trunk/LogicMail/src/org/logicprobe/LogicMail/model
- Files:
-
- 2 edited
-
MailFileManager.java (modified) (2 diffs)
-
MailboxNode.java (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailFileManager.java
r693 r697 35 35 import java.io.IOException; 36 36 import java.util.Enumeration; 37 import java.util.Hashtable; 37 38 import java.util.Vector; 38 39 … … 436 437 } 437 438 439 public synchronized void removeStaleMessageNodes(MailboxNode mailboxNode, String[] uidsToRetain) throws IOException { 440 if(cacheUrl == null) { return; } 441 442 Hashtable retentionSet = new Hashtable(); 443 for(int i=0; i<uidsToRetain.length; i++) { 444 retentionSet.put(uidsToRetain[i], Boolean.TRUE); 445 } 446 447 String[] fileUrls = getMessageFiles(mailboxNode); 448 Vector fileUrlsToDelete = new Vector(); 449 for(int i=0; i<fileUrls.length; i++) { 450 int p = fileUrls[i].lastIndexOf('/'); 451 int q = fileUrls[i].lastIndexOf('.'); 452 if(p != -1 && q != -1 && p < q) { 453 String messageUid = fileUrls[i].substring(p + 1, q); 454 if(!retentionSet.containsKey(messageUid)) { 455 fileUrlsToDelete.addElement(fileUrls[i]); 456 } 457 } 458 } 459 460 int size = fileUrlsToDelete.size(); 461 for(int i=0; i<size; i++) { 462 try { 463 FileConnection fc = (FileConnection)Connector.open((String)fileUrlsToDelete.elementAt(i)); 464 if(fc.exists() && fc.canRead()) { 465 fc.delete(); 466 } 467 } catch (IOException exp) { 468 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 469 EventLogger.logEvent(AppInfo.GUID, 470 ("Error deleting message from cache: " + exp.toString()).getBytes(), 471 EventLogger.DEBUG_INFO); 472 } 473 } 474 } 475 } 476 438 477 public synchronized void removeMessageNodes(MailboxNode mailboxNode, MessageToken[] messageTokens) throws IOException { 439 478 if(cacheUrl == null) { return; } -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailboxNode.java
r693 r697 77 77 private Vector pendingExpungeMessages = new Vector(); 78 78 79 /** Set of messages being loaded from cache. */ 79 80 private Hashtable messagesBeingLoaded = new Hashtable(); 81 /** Map of unapplied message flag updates received from the server. */ 80 82 private Hashtable unappliedFlagUpdates = new Hashtable(); 83 /** Set of messages known to the server. */ 84 private Hashtable messagesKnownToServer = new Hashtable(); 85 86 /** Flag to keep track of external requests for cache cleanup. */ 87 private boolean removeMessagesNotOnServerRequested; 88 89 /** Flag to keep track of initial cache load process. */ 90 private boolean cacheLoadInProgress; 81 91 82 92 /** … … 637 647 } 638 648 639 640 649 /** 641 650 * Removes all messages not marked as existing on the server. 642 651 */ 643 void removeMessagesNotOnServer() {652 void removeMessagesNotOnServer() { 644 653 synchronized(messages) { 645 Vector messagesToRemove = new Vector(); 646 647 // Populate a list of the messages to remove 648 int size = messages.size(); 649 for(int i=0; i<size; i++) { 650 MessageNode messageNode = (MessageNode)messages.elementAt(i); 651 if(!messageNode.existsOnServer()) { 652 messagesToRemove.addElement(messageNode); 653 } 654 } 655 656 size = messagesToRemove.size(); 657 if(size == 0) { return; } 658 654 // If cache load is in progress, take note of request and return 655 if(cacheLoadInProgress) { 656 removeMessagesNotOnServerRequested = true; 657 } 658 else { 659 removeMessagesNotOnServerImpl(); 660 } 661 } 662 } 663 664 private void removeMessagesNotOnServerImpl() { 665 Vector messagesToRemove = new Vector(); 666 Vector messagesToRetain = new Vector(); 667 668 // Populate a list of the messages to remove 669 int size = messages.size(); 670 for(int i=0; i<size; i++) { 671 MessageNode messageNode = (MessageNode)messages.elementAt(i); 672 if(!messageNode.existsOnServer()) { 673 messagesToRemove.addElement(messageNode); 674 } 675 else { 676 String messageUid = messageNode.getMessageToken().getMessageUid(); 677 messagesToRetain.addElement(messageUid); 678 messagesKnownToServer.remove(messageUid); 679 } 680 } 681 682 // Iterate through any remaining items in our server-known message set, 683 // and add them to the retention list. 684 for(Enumeration e = messagesKnownToServer.keys(); e.hasMoreElements(); ) { 685 messagesToRetain.addElement(e.nextElement()); 686 } 687 688 size = messagesToRemove.size(); 689 if(size > 0) { 659 690 MessageNode[] removedMessageNodes = new MessageNode[size]; 660 MessageToken[] tokensToRemove = new MessageToken[size];661 691 for(int i=0; i<size; i++) { 662 692 MessageNode messageNode = (MessageNode)messagesToRemove.elementAt(i); … … 666 696 messageTokenMap.remove(messageNode.getMessageToken()); 667 697 messageTokenUidSet.remove(messageNode.getMessageToken().getMessageUid()); 668 tokensToRemove[i] = messageNode.getMessageToken();669 698 removedMessageNodes[i] = messageNode; 670 699 } 671 700 672 701 if(this.getParentAccount().getStatus() != AccountNode.STATUS_LOCAL) { 673 (new RemoveFromCacheThread( tokensToRemove)).start();702 (new RemoveFromCacheThread(messagesToRetain)).start(); 674 703 } 675 704 updateUnseenMessages(false); 676 705 fireMailboxStatusChanged(MailboxNodeEvent.TYPE_DELETED_MESSAGES, removedMessageNodes); 677 706 } 707 else { 708 if(this.getParentAccount().getStatus() != AccountNode.STATUS_LOCAL) { 709 (new RemoveFromCacheThread(messagesToRetain)).start(); 710 } 711 } 678 712 } 679 713 680 714 private class RemoveFromCacheThread extends Thread { 681 private MessageToken[] messageTokens;715 private String[] uidsToRetain; 682 716 683 public RemoveFromCacheThread(MessageToken[] messageTokens) { 684 this.messageTokens = messageTokens; 717 public RemoveFromCacheThread(Vector uidsToRetain) { 718 this.uidsToRetain = new String[uidsToRetain.size()]; 719 uidsToRetain.copyInto(this.uidsToRetain); 685 720 } 686 721 … … 688 723 yield(); 689 724 try { 690 MailFileManager.getInstance().remove MessageNodes(MailboxNode.this, messageTokens);725 MailFileManager.getInstance().removeStaleMessageNodes(MailboxNode.this, uidsToRetain); 691 726 } catch (IOException e) { 692 727 EventLogger.logEvent(AppInfo.GUID, … … 712 747 boolean updateMessageFlags(MessageToken messageToken, MessageFlags messageFlags) { 713 748 boolean result = false; 714 synchronized(messages) { 715 if(messagesBeingLoaded.containsKey(messageToken.getMessageUid())) { 716 unappliedFlagUpdates.put(messageToken.getMessageUid(), new Object[] { messageToken, messageFlags }); 717 result = true; 718 } 719 else { 720 MessageNode messageNode = (MessageNode)messageTokenMap.get(messageToken); 721 if(messageNode != null) { 722 // Message already exists in the mailbox, and just needs 723 // its flags updated. 724 messageNode.setFlags(MessageNode.convertMessageFlags(messageFlags)); 725 726 // Update the token based on the token that came along 727 // with the flags. This will update any volatile state 728 // information, such as POP message indices 729 messageNode.getMessageToken().updateToken(messageToken); 730 messageNode.setExistsOnServer(true); 731 749 synchronized(fetchLock) { 750 synchronized(messages) { 751 // If this method is called during the initial flags fetch, then 752 // track all messages updates are received for. This is how we 753 // build a collection of messages that exist on the server, for the 754 // purposes of cache cleanup. 755 756 if(fetchFlagsOnly) { 757 messagesKnownToServer.put(messageToken.getMessageUid(), Boolean.TRUE); 758 } 759 if(messagesBeingLoaded.containsKey(messageToken.getMessageUid())) { 760 unappliedFlagUpdates.put(messageToken.getMessageUid(), new Object[] { messageToken, messageFlags }); 732 761 result = true; 762 } 763 else { 764 MessageNode messageNode = (MessageNode)messageTokenMap.get(messageToken); 765 if(messageNode != null) { 766 // Message already exists in the mailbox, and just needs 767 // its flags updated. 768 messageNode.setFlags(MessageNode.convertMessageFlags(messageFlags)); 769 770 // Update the token based on the token that came along 771 // with the flags. This will update any volatile state 772 // information, such as POP message indices 773 messageNode.getMessageToken().updateToken(messageToken); 774 messageNode.setExistsOnServer(true); 775 776 result = true; 777 } 733 778 } 734 779 } … … 997 1042 if(parentAccount.getAccountConfig() != null) { 998 1043 if(fetchThread == null || !fetchThread.isAlive()) { 1044 synchronized(messages) { 1045 cacheLoadInProgress = true; 1046 } 1047 999 1048 // Request flags and tokens for recent messages from the mail store 1000 1049 parentAccount.getMailStore().requestFolderMessagesRecent( … … 1022 1071 1023 1072 private class RefreshMessagesThread extends Thread implements MessageNodeCallback { 1073 private Vector messagesToAdd = new Vector(); 1074 1024 1075 public RefreshMessagesThread() { 1025 1076 … … 1030 1081 try { 1031 1082 MailFileManager.getInstance().readMessageNodes(MailboxNode.this, this); 1083 addLoadedMessages(); 1084 1085 // If the server fetch completed before the cache load, then 1086 // execute the pending post-load cache cleanup. 1087 synchronized(messages) { 1088 cacheLoadInProgress = false; 1089 if(removeMessagesNotOnServerRequested) { 1090 removeMessagesNotOnServerRequested = false; 1091 removeMessagesNotOnServerImpl(); 1092 } 1093 } 1032 1094 } catch (IOException e) { 1033 1095 EventLogger.logEvent(AppInfo.GUID, … … 1042 1104 synchronized(messages) { 1043 1105 if(messageTokenUidSet.containsKey(messageUid)) { 1106 // Don't load messages that have already been loaded 1044 1107 result = false; 1045 1108 } 1046 1109 else { 1110 // Keep track of messages that will be loaded 1047 1111 messagesBeingLoaded.put(messageUid, Boolean.TRUE); 1048 1112 result = true; … … 1065 1129 } 1066 1130 } 1067 MailboxNode.this.addMessage(messageNode); 1068 } 1131 messagesToAdd.addElement(messageNode); 1132 if(messagesToAdd.size() == 4) { 1133 addLoadedMessages(); 1134 } 1135 } 1136 } 1137 1138 private void addLoadedMessages() { 1139 int size = messagesToAdd.size(); 1140 if(size == 0) { return; } 1141 1142 MessageNode[] messageArray = new MessageNode[size]; 1143 messagesToAdd.copyInto(messageArray); 1144 messagesToAdd.removeAllElements(); 1145 MailboxNode.this.addMessages(messageArray); 1069 1146 } 1070 1147 }
Note: See TracChangeset
for help on using the changeset viewer.
