diff options
author | Dmitry Isaikin <isaikin-dmitry@yandex.ru> | 2016-05-17 05:22:59 +0400 |
---|---|---|
committer | HoĆ V. DINH <dinh.viet.hoa@gmail.com> | 2016-05-16 18:22:59 -0700 |
commit | df85a8925e4de9480a5a153f3101486743979570 (patch) | |
tree | 3f613d1da44c4fa385d1bc198bc881349fb9697a /src | |
parent | ced3f8648d116cf1bba1ff106093c7148df129ce (diff) |
Try to use IMAP connection with minimum queue size among connections that already selected into needed folder (#1404)
Diffstat (limited to 'src')
-rwxr-xr-x | src/async/imap/MCIMAPAsyncSession.cpp | 109 | ||||
-rwxr-xr-x | src/async/imap/MCIMAPAsyncSession.h | 10 |
2 files changed, 78 insertions, 41 deletions
diff --git a/src/async/imap/MCIMAPAsyncSession.cpp b/src/async/imap/MCIMAPAsyncSession.cpp index af8a8dfa..5c599558 100755 --- a/src/async/imap/MCIMAPAsyncSession.cpp +++ b/src/async/imap/MCIMAPAsyncSession.cpp @@ -286,11 +286,21 @@ IMAPAsyncConnection * IMAPAsyncSession::session() IMAPAsyncConnection * IMAPAsyncSession::sessionForFolder(String * folder, bool urgent) { if (folder == NULL) { - return availableSession(); + return matchingSessionForFolder(NULL); } else { IMAPAsyncConnection * s = NULL; + + // try find session with empty queue, selected to the folder + s = sessionWithMinQueue(true, folder); + if (s != NULL && s->operationsCount() == 0) { + s->setLastFolder(folder); + return s; + } + if (urgent && mAllowsFolderConcurrentAccessEnabled) { + // in urgent mode try reuse any available session with + // empty queue or create new one, if maximum connections limit does not reached. s = availableSession(); if (s->operationsCount() == 0) { s->setLastFolder(folder); @@ -298,6 +308,7 @@ IMAPAsyncConnection * IMAPAsyncSession::sessionForFolder(String * folder, bool u } } + // otherwise returns session with minimum size of queue among selected to the folder. s = matchingSessionForFolder(folder); s->setLastFolder(folder); return s; @@ -306,58 +317,74 @@ IMAPAsyncConnection * IMAPAsyncSession::sessionForFolder(String * folder, bool u IMAPAsyncConnection * IMAPAsyncSession::availableSession() { - if (mMaximumConnections == 0) { - for(unsigned int i = 0 ; i < mSessions->count() ; i ++) { - IMAPAsyncConnection * s = (IMAPAsyncConnection *) mSessions->objectAtIndex(i); - if (s->operationsCount() == 0) - return s; - } - IMAPAsyncConnection * chosenSession = session(); + // try find existant session with empty queue for reusing. + IMAPAsyncConnection * chosenSession = sessionWithMinQueue(false, NULL); + if ((chosenSession != NULL) && (chosenSession->operationsCount() == 0)) { + return chosenSession; + } + + // create new session, if maximum connections limit does not reached yet. + if ((mMaximumConnections == 0) || (mSessions->count() < mMaximumConnections)) { + chosenSession = session(); mSessions->addObject(chosenSession); return chosenSession; } - else { - IMAPAsyncConnection * chosenSession = NULL; - unsigned int minOperationsCount = 0; - for(unsigned int i = 0 ; i < mSessions->count() ; i ++) { - IMAPAsyncConnection * s = (IMAPAsyncConnection *) mSessions->objectAtIndex(i); - if (chosenSession == NULL) { - chosenSession = s; - minOperationsCount = s->operationsCount(); - } - else if (s->operationsCount() < minOperationsCount) { - chosenSession = s; - minOperationsCount = s->operationsCount(); - } - } - if (mSessions->count() < mMaximumConnections) { - if ((chosenSession != NULL) && (minOperationsCount == 0)) { - return chosenSession; - } - chosenSession = session(); - mSessions->addObject(chosenSession); - return chosenSession; + + // otherwise returns existant session with minimum size of queue. + return chosenSession; +} + +IMAPAsyncConnection * IMAPAsyncSession::matchingSessionForFolder(String * folder) +{ + IMAPAsyncConnection * s = NULL; + if (folder == NULL) { + // try find session with minimum size of queue among non-selected to the any folder. + s = sessionWithMinQueue(true, NULL); + + if (s == NULL) { + // prefer to use INBOX-selected folders for commands does not tight to specific folder. + s = sessionWithMinQueue(true, MCSTR("INBOX")); } - else { - return chosenSession; + } else { + // try find session with minimum size of queue among selected to the folder. + s = sessionWithMinQueue(true, folder); + + if (s == NULL) { + // try find session with minimum size of queue among non-selected to any folder ones. + s = sessionWithMinQueue(true, NULL); } } + + if (s != NULL) { + return s; + } + + // otherwise returns existant session with minumum size of queue or create new one. + return availableSession(); } -IMAPAsyncConnection * IMAPAsyncSession::matchingSessionForFolder(String * folder) +IMAPAsyncConnection * IMAPAsyncSession::sessionWithMinQueue(bool filterByFolder, String * folder) { - for(unsigned int i = 0 ; i < mSessions->count() ; i ++) { - IMAPAsyncConnection * currentSession = (IMAPAsyncConnection *) mSessions->objectAtIndex(i); - if (currentSession->lastFolder() != NULL) { - if (currentSession->lastFolder()->isEqual(folder)) { - return currentSession; + IMAPAsyncConnection * chosenSession = NULL; + unsigned int minOperationsCount = 0; + + for (unsigned int i = 0 ; i < mSessions->count() ; i ++) { + IMAPAsyncConnection * s = (IMAPAsyncConnection *) mSessions->objectAtIndex(i); + if ((chosenSession == NULL) || (s->operationsCount() < minOperationsCount)) { + bool matched = true; + if (filterByFolder) { + // filter by last selested folder + matched = ((folder != NULL && s->lastFolder() != NULL && s->lastFolder()->isEqual(folder)) + || (folder == NULL && s->lastFolder() == NULL)); + } + if (matched) { + chosenSession = s; + minOperationsCount = s->operationsCount(); } - } - else { - return currentSession; } } - return availableSession(); + + return chosenSession; } IMAPFolderInfoOperation * IMAPAsyncSession::folderInfoOperation(String * folder) diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 78ebd9b9..0230deda 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -212,8 +212,18 @@ namespace mailcore { String * mGmailUserDisplayName; bool mIdleEnabled; + /*! Create new IMAP session */ virtual IMAPAsyncConnection * session(); + /*! Returns a new or an existing session, it is best suited to run the IMAP command + in the specified folder. */ virtual IMAPAsyncConnection * matchingSessionForFolder(String * folder); + /*! Returns a session with minimum operation queue among already created ones. + If @param filterByFolder is true, then function filters sessions with + predicate (lastFolder() EQUALS TO @param folder). In case of @param folder is NULL + the function would search a session among non-selected ones. */ + virtual IMAPAsyncConnection * sessionWithMinQueue(bool filterByFolder, String * folder); + /*! Returns existant or new session with empty operation queue, if it can. + Otherwise, returns the session with the minimum size of the operation queue. */ virtual IMAPAsyncConnection * availableSession(); virtual IMAPMessageRenderingOperation * renderingOperation(IMAPMessage * message, String * folder, |