Ignore:
Timestamp:
08/22/10 14:10:19 (18 months ago)
Author:
octorian
Message:

Made cache loading and flags refresh happen simultaneously. Still need to work cache-file cleanup.

Location:
trunk/LogicMail/src/org/logicprobe/LogicMail
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/AccountNode.java

    r670 r693  
    610610                // Only flags have been retrieved, so the existing messages need to 
    611611                // be checked and additional actions requested accordingly. 
    612                 //TODO: Implement flags-only logic 
    613612                    for (int i = 0; i < folderMessages.length; i++) { 
    614                         MessageNode messageNode = 
    615                                 mailboxNode.getMessageByToken(folderMessages[i].getMessageToken()); 
    616                         if(messageNode != null) { 
    617                                 messageNode.setFlags(MessageNode.convertMessageFlags(folderMessages[i].getFlags())); 
    618                                  
    619                                 // Update the token based on the token that came along 
    620                                 // with the flags.  This will update any volatile state 
    621                                 // information, such as POP message indices 
    622                                 messageNode.getMessageToken().updateToken(folderMessages[i].getMessageToken()); 
    623                                 messageNode.setExistsOnServer(true); 
    624                         } 
    625                         else { 
    626                             synchronized(folderMessagesToFetch) { 
    627                                 Vector messagesToFetch = (Vector)folderMessagesToFetch.get(e.getFolder()); 
    628                                 if(messagesToFetch == null) { 
    629                                     messagesToFetch = new Vector(); 
    630                                     folderMessagesToFetch.put(e.getFolder(), messagesToFetch); 
    631                                 } 
    632                                 messagesToFetch.addElement(folderMessages[i].getMessageToken()); 
    633                             } 
    634                         } 
     613                        if(!mailboxNode.updateMessageFlags(folderMessages[i].getMessageToken(), folderMessages[i].getFlags())) { 
     614                        // Message does not currently exist in the mailbox, and 
     615                        // is not in the process of being loaded from cache. 
     616                        synchronized(folderMessagesToFetch) { 
     617                            Vector messagesToFetch = (Vector)folderMessagesToFetch.get(e.getFolder()); 
     618                            if(messagesToFetch == null) { 
     619                                messagesToFetch = new Vector(); 
     620                                folderMessagesToFetch.put(e.getFolder(), messagesToFetch); 
     621                            } 
     622                            messagesToFetch.addElement(folderMessages[i].getMessageToken()); 
     623                        } 
     624                        } 
    635625                    } 
    636626            } 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailFileManager.java

    r628 r693  
    232232         
    233233        String[] fileUrls = getMessageFiles(mailboxNode); 
     234        Vector fileUrlsToLoad = new Vector(fileUrls.length); 
    234235        for(int i=0; i<fileUrls.length; i++) { 
    235             MessageNode messageNode = readMessageNode(fileUrls[i]); 
     236            int p = fileUrls[i].lastIndexOf('/'); 
     237            int q = fileUrls[i].lastIndexOf('.'); 
     238            if(p != -1 && q != -1 && p < q) { 
     239                String messageUid = fileUrls[i].substring(p + 1, q); 
     240                if(callback.messageNodeAvailable(messageUid)) { 
     241                    fileUrlsToLoad.addElement(fileUrls[i]); 
     242                } 
     243            } 
     244        } 
     245         
     246        int size = fileUrlsToLoad.size(); 
     247        for(int i=0; i<size; i++) { 
     248            MessageNode messageNode = readMessageNode((String)fileUrlsToLoad.elementAt(i)); 
    236249            if(messageNode != null) { 
    237250                if(loadContent) { 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailboxNode.java

    r655 r693  
    6969        private Hashtable messageMap; 
    7070        private Hashtable messageTokenMap; 
     71        private Hashtable messageTokenUidSet; 
    7172        private EventListenerList listenerList = new EventListenerList(); 
    7273        private int type; 
     
    7576        private int unseenMessageCount; 
    7677    private Vector pendingExpungeMessages = new Vector(); 
     78     
     79    private Hashtable messagesBeingLoaded = new Hashtable(); 
     80    private Hashtable unappliedFlagUpdates = new Hashtable(); 
    7781     
    7882    /** 
     
    144148                this.messageMap = new Hashtable(); 
    145149                this.messageTokenMap = new Hashtable(); 
     150                this.messageTokenUidSet = new Hashtable(); 
    146151                if(folderTreeItem != null) { 
    147152                        this.setFolderTreeItem(new FolderTreeItem(folderTreeItem)); 
     
    539544                boolean messageAdded; 
    540545                synchronized(messages) { 
     546                    messagesBeingLoaded.remove(message.getMessageToken().getMessageUid()); 
    541547                        messageAdded = addMessageImpl(message); 
    542548                } 
     
    587593                        messageMap.put(message, message); 
    588594                        messageTokenMap.put(message.getMessageToken(), message); 
     595                        messageTokenUidSet.put(message.getMessageToken().getMessageUid(), Boolean.TRUE); 
     596                         
     597                        Object[] element = (Object[])unappliedFlagUpdates.remove( 
     598                                message.getMessageToken().getMessageUid()); 
     599                        if(element != null) { 
     600                            MessageToken messageToken = (MessageToken)element[0]; 
     601                            MessageFlags messageFlags = (MessageFlags)element[1]; 
     602                // Message already exists in the mailbox, and just needs 
     603                // its flags updated. 
     604                            message.setFlags(MessageNode.convertMessageFlags(messageFlags)); 
     605 
     606                // Update the token based on the token that came along 
     607                // with the flags.  This will update any volatile state 
     608                // information, such as POP message indices 
     609                            message.getMessageToken().updateToken(messageToken); 
     610                            message.setExistsOnServer(true); 
     611                        } 
    589612                        message.commitMessage(); 
    590613                        return true; 
     
    607630                                messageMap.remove(message); 
    608631                                messageTokenMap.remove(message.getMessageToken()); 
     632                                messageTokenUidSet.remove(message.getMessageToken().getMessageUid()); 
    609633                        } 
    610634                } 
     
    641665                messageMap.remove(messageNode); 
    642666                messageTokenMap.remove(messageNode.getMessageToken()); 
     667                messageTokenUidSet.remove(messageNode.getMessageToken().getMessageUid()); 
    643668                tokensToRemove[i] = messageNode.getMessageToken(); 
    644669                removedMessageNodes[i] = messageNode; 
     
    674699 
    675700    /** 
     701     * Attempt to update the flags for a message within this mailbox. 
     702     * If the <code>MessageNode</code> for the token already exists within 
     703     * the mailbox, its flags will be updated.  If it does not exist, but is in 
     704     * the process of being loaded from cache, the flag change will be saved 
     705     * and applied as the message load completes.  If the message neither 
     706     * exists nor is being loaded, false will be returned. 
     707     * 
     708     * @param messageToken the message token 
     709     * @param messageFlags the flags to update 
     710     * @return true, if the update was applied or saved 
     711     */ 
     712    boolean updateMessageFlags(MessageToken messageToken, MessageFlags messageFlags) { 
     713        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 
     732                    result = true; 
     733                } 
     734            } 
     735        } 
     736        return result; 
     737    } 
     738     
     739    /** 
    676740     * Called when the mail store notifies of a completed expunge operation on 
    677741     * this folder, so anything we expected to be expunged can be cleaned out. 
     
    702766                        messageMap.clear(); 
    703767                        messageTokenMap.clear(); 
     768                        messageTokenUidSet.clear(); 
    704769                } 
    705770        updateUnseenMessages(false); 
     
    932997            if(parentAccount.getAccountConfig() != null) { 
    933998                if(fetchThread == null || !fetchThread.isAlive()) { 
     999                    // Request flags and tokens for recent messages from the mail store 
     1000                    parentAccount.getMailStore().requestFolderMessagesRecent( 
     1001                            folderTreeItem, 
     1002                            fetchFlagsOnly, 
     1003                            new MailStoreRequestCallback() { 
     1004                                public void mailStoreRequestComplete() { 
     1005                                    synchronized(fetchLock) { 
     1006                                        fetchFlagsOnly = false; 
     1007                                    } 
     1008                                } 
     1009                                public void mailStoreRequestFailed(Throwable exception) { } 
     1010                            }); 
     1011                     
     1012                    // Start the cache loading process 
    9341013                    fetchThread = new RefreshMessagesThread(); 
    9351014                    fetchThread.start(); 
     
    9591038        } 
    9601039 
     1040        public boolean messageNodeAvailable(String messageUid) { 
     1041            boolean result; 
     1042            synchronized(messages) { 
     1043                if(messageTokenUidSet.containsKey(messageUid)) { 
     1044                    result = false; 
     1045                } 
     1046                else { 
     1047                    messagesBeingLoaded.put(messageUid, Boolean.TRUE); 
     1048                    result = true; 
     1049                } 
     1050            } 
     1051            return result; 
     1052        } 
     1053 
    9611054        public void messageNodeUpdated(MessageNode messageNode) { 
    9621055            if(messageNode != null) { 
     1056                // If the initial flags fetch is complete, then ignore all 
     1057                // nodes loaded from cache that don't have pending flag updates. 
     1058                synchronized(fetchLock) { 
     1059                    if(!fetchFlagsOnly) { 
     1060                        synchronized(messages) { 
     1061                            if(!unappliedFlagUpdates.containsKey(messageNode.getMessageToken().getMessageUid())) { 
     1062                                return; 
     1063                            } 
     1064                        } 
     1065                    } 
     1066                } 
    9631067                MailboxNode.this.addMessage(messageNode); 
    9641068            } 
    965             else { 
    966                 // Request flags and tokens for recent messages from the mail store 
    967                 parentAccount.getMailStore().requestFolderMessagesRecent( 
    968                         folderTreeItem, 
    969                         fetchFlagsOnly, 
    970                         new MailStoreRequestCallback() { 
    971                             public void mailStoreRequestComplete() { 
    972                                 synchronized(fetchLock) { 
    973                                     fetchFlagsOnly = false; 
    974                                 } 
    975                             } 
    976                             public void mailStoreRequestFailed(Throwable exception) { } 
    977                         }); 
    978             } 
    979         }         
     1069        } 
    9801070    } 
    9811071     
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MessageNodeCallback.java

    r564 r693  
    3838public interface MessageNodeCallback { 
    3939    /** 
     40     * Called when a <code>MessageNode</code> is about to be loaded, to check 
     41     * whether or not to proceed with the load operation. 
     42     * Since this is expected to be called from <code>MailFileManager</code> 
     43     * prior to actually loading message data, only the filename-based UID can 
     44     * be provided. 
     45     *  
     46     * @param messageUid the string-form UID for the message to be loaded 
     47     * @return true, if the message should be loaded 
     48     */ 
     49    boolean messageNodeAvailable(String messageUid); 
     50     
     51    /** 
    4052     * Called when a <code>MessageNode</code> is created or updated, 
    4153     * depending on the purpose of the method that invoked the this 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/OutboxMailboxNode.java

    r672 r693  
    196196        } 
    197197 
     198        public boolean messageNodeAvailable(String messageUid) { 
     199            return true; 
     200        } 
     201         
    198202        public void messageNodeUpdated(MessageNode messageNode) { 
    199203            if(messageNode instanceof OutgoingMessageNode) { 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/ui/MailHomeScreen.java

    r672 r693  
    441441 
    442442    public void refreshMailTreeNode(MailHomeTreeNode node) { 
    443         int nodeId = nodeIdMap.get(node); 
     443        final int nodeId = nodeIdMap.get(node); 
    444444        if(nodeId != -1) { 
    445             synchronized(UiApplication.getEventLock()) { 
    446                 treeField.invalidateNode(nodeId); 
    447             } 
     445            UiApplication.getUiApplication().invokeLater(new Runnable() { 
     446                public void run() { 
     447                    treeField.invalidateNode(nodeId); 
     448                } 
     449            }); 
    448450        } 
    449451    } 
Note: See TracChangeset for help on using the changeset viewer.