From 710e2748498ed97e7086b0dc3c40f11b29aeec8f Mon Sep 17 00:00:00 2001 From: alecpl Date: Wed, 20 Oct 2010 13:33:27 +0000 Subject: - Improve performance of unseen messages counting, use STATUS instead of SELECT+SEARCH (#1487058) --- CHANGELOG | 1 + program/include/rcube_imap_generic.php | 69 ++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b1502152d..ad733e6be 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -37,6 +37,7 @@ CHANGELOG Roundcube Webmail - Add METADATA extension support into IMAP classes (RFC5464) - Fix decoding of e-mail address strings in message headers (#1487068) - Fix handling of attachments when Content-Disposition is not inline nor attachment (#1487051) +- Improve performance of unseen messages counting (#1487058) RELEASE 0.4.2 ------------- diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php index e7e858f09..4c082b9e4 100644 --- a/program/include/rcube_imap_generic.php +++ b/program/include/rcube_imap_generic.php @@ -733,6 +733,41 @@ class rcube_imap_generic return false; } + /** + * Executes STATUS comand + * + * @param string $mailbox Mailbox name + * @param array $items Requested item names + * + * @return array Status item-value hash + * @access public + * @since 0.5-beta + */ + function status($mailbox, $items) + { + if (empty($mailbox) || empty($items)) { + return false; + } + + list($code, $response) = $this->execute('STATUS', array($this->escape($mailbox), + '(' . implode(' ', (array) $items) . ')')); + + if ($code == self::ERROR_OK && preg_match('/\* STATUS /i', $response)) { + $result = array(); + $response = substr($response, 9); // remove prefix "* STATUS " + + list($mbox, $items) = $this->tokenizeResponse($response, 2); + + for ($i=0, $len=count($items); $i<$len; $i += 2) { + $result[$items[$i]] = (int) $items[$i+1]; + } + + return $result; + } + + return false; + } + function checkForRecent($mailbox) { if (empty($mailbox)) { @@ -761,6 +796,32 @@ class rcube_imap_generic return false; } + /** + * Returns count of messages without \Seen flag in a specified folder + * + * @param string $mailbox Mailbox name + * + * @return int Number of messages, False on error + * @access public + */ + function countUnseen($mailbox) + { + // Try STATUS, should be faster + $counts = $this->status($mailbox, array('UNSEEN')); + if (is_array($counts)) { + return (int) $counts['UNSEEN']; + } + + // Invoke SEARCH as a fallback + // @TODO: ESEARCH support + $index = $this->search($mailbox, 'ALL UNSEEN'); + if (is_array($index)) { + return count($index); + } + + return false; + } + function sort($mailbox, $field, $add='', $is_uid=FALSE, $encoding = 'US-ASCII') { $field = strtoupper($field); @@ -1413,14 +1474,6 @@ class rcube_imap_generic return $result; } - function countUnseen($folder) - { - $index = $this->search($folder, 'ALL UNSEEN'); - if (is_array($index)) - return count($index); - return false; - } - // Don't be tempted to change $str to pass by reference to speed this up - it will slow it down by about // 7 times instead :-) See comments on http://uk2.php.net/references and this article: // http://derickrethans.nl/files/phparch-php-variables-article.pdf -- cgit v1.2.3