summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2010-10-30 15:06:31 +0000
committeralecpl <alec@alec.pl>2010-10-30 15:06:31 +0000
commit36911ea111b3e633b9157ed306022b026e72dd60 (patch)
tree0acb92c169bb1be59e0febf2eb918fcf22c283b7
parent9ae29c9525dbd878cff63d691625bb0c6f6cbf5c (diff)
- Improve performance by invoking STATUS command once for both MESSAGES and UNSEEN counters
-rw-r--r--program/include/rcube_imap_generic.php56
1 files changed, 49 insertions, 7 deletions
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);
}