From 36911ea111b3e633b9157ed306022b026e72dd60 Mon Sep 17 00:00:00 2001 From: alecpl Date: Sat, 30 Oct 2010 15:06:31 +0000 Subject: - Improve performance by invoking STATUS command once for both MESSAGES and UNSEEN counters --- program/include/rcube_imap_generic.php | 56 +++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) (limited to 'program') diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php index a7bfe05ad..1f176b682 100644 --- a/program/include/rcube_imap_generic.php +++ b/program/include/rcube_imap_generic.php @@ -900,18 +900,27 @@ class rcube_imap_generic * Executes STATUS comand * * @param string $mailbox Mailbox name - * @param array $items Requested item names + * @param array $items Additional requested item names. By default + * MESSAGES and UNSEEN are requested. Other defined + * in RFC3501: UIDNEXT, UIDVALIDITY, RECENT * * @return array Status item-value hash * @access public * @since 0.5-beta */ - function status($mailbox, $items) + function status($mailbox, $items=array()) { - if (empty($mailbox) || empty($items)) { + if (empty($mailbox)) { return false; } + if (!in_array('MESSAGES', $items)) { + $items[] = 'MESSAGES'; + } + if (!in_array('UNSEEN', $items)) { + $items[] = 'UNSEEN'; + } + list($code, $response) = $this->execute('STATUS', array($this->escape($mailbox), '(' . implode(' ', (array) $items) . ')')); @@ -925,6 +934,8 @@ class rcube_imap_generic $result[$items[$i]] = (int) $items[$i+1]; } + $this->data['STATUS:'.$mailbox] = $result; + return $result; } @@ -955,8 +966,14 @@ class rcube_imap_generic return $this->data['EXISTS']; } - // Try STATUS, should be faster - $counts = $this->status($mailbox, array('MESSAGES')); + // Check internal cache + $cache = $this->data['STATUS:'.$mailbox]; + if (!empty($cache) && isset($cache['MESSAGES'])) { + return (int) $cache['MESSAGES']; + } + + // Try STATUS (should be faster than SELECT) + $counts = $this->status($mailbox); if (is_array($counts)) { return (int) $counts['MESSAGES']; } @@ -974,8 +991,14 @@ class rcube_imap_generic */ function countUnseen($mailbox) { - // Try STATUS, should be faster - $counts = $this->status($mailbox, array('UNSEEN')); + // Check internal cache + $cache = $this->data['STATUS:'.$mailbox]; + if (!empty($cache) && isset($cache['UNSEEN'])) { + return (int) $cache['UNSEEN']; + } + + // Try STATUS (should be faster than SELECT+SEARCH) + $counts = $this->status($mailbox); if (is_array($counts)) { return (int) $counts['UNSEEN']; } @@ -1602,6 +1625,9 @@ class rcube_imap_generic return false; } + // Clear internal status cache + unset($this->data['STATUS:'.$mailbox]); + $result = $this->execute($messages ? 'UID EXPUNGE' : 'EXPUNGE', array($messages), self::COMMAND_NORESPONSE); @@ -1623,6 +1649,11 @@ class rcube_imap_generic return false; } + // Clear internal status cache + if ($flag == 'SEEN') { + unset($this->data['STATUS:'.$mailbox]['UNSEEN']); + } + $flag = $this->flags[strtoupper($flag)]; $result = $this->execute('UID STORE', array( $this->compressMessageSet($messages), $mod . 'FLAGS.SILENT', "($flag)"), @@ -1653,6 +1684,9 @@ class rcube_imap_generic return false; } + // Clear internal status cache + unset($this->data['STATUS:'.$to]); + $result = $this->execute('UID COPY', array( $this->compressMessageSet($messages), $this->escape($to)), self::COMMAND_NORESPONSE); @@ -1669,6 +1703,9 @@ class rcube_imap_generic $r = $this->copy($messages, $from, $to); if ($r) { + // Clear internal status cache + unset($this->data['STATUS:'.$from]); + return $this->delete($from, $messages); } return $r; @@ -2259,6 +2296,9 @@ class rcube_imap_generic $line = $this->readLine(); } while (!$this->startsWith($line, $key, true, true)); + // Clear internal status cache + unset($this->data['STATUS:'.$folder]); + return ($this->parseResult($line, 'APPEND: ') == self::ERROR_OK); } else { @@ -2333,6 +2373,8 @@ class rcube_imap_generic $line = $this->readLine(); } while (!$this->startsWith($line, $key, true, true)); + // Clear internal status cache + unset($this->data['STATUS:'.$folder]); return ($this->parseResult($line, 'APPEND: ') == self::ERROR_OK); } -- cgit v1.2.3