- Improve performance of message cache status checking when skip_disabled=true

release-0.6
alecpl 14 years ago
parent 93272ea91b
commit 9ae29c9525

@ -57,6 +57,7 @@ CHANGELOG Roundcube Webmail
- Plugin API: add possibility to disable plugin in AJAX mode, 'noajax' property
- Plugin API: add possibility to disable plugin in framed mode, 'noframe' property
- Improve performance of setting IMAP flags using .SILENT suffix
- Improve performance of message cache status checking with skip_disabled=true
RELEASE 0.4.2
-------------

@ -546,9 +546,14 @@ class rcube_imap
if ($mode == 'UNSEEN') {
$search_str .= " UNSEEN";
}
else if ($status) {
$keys[] = 'MAX';
$need_uid = true;
else {
if ($this->caching_enabled) {
$keys[] = 'ALL';
}
if ($status) {
$keys[] = 'MAX';
$need_uid = true;
}
}
// get message count using (E)SEARCH
@ -557,9 +562,15 @@ class rcube_imap
$count = is_array($index) ? $index['COUNT'] : 0;
if ($mode == 'ALL' && $status) {
$this->set_folder_stats($mailbox, 'cnt', $count);
$this->set_folder_stats($mailbox, 'maxuid', is_array($index) ? $index['MAX'] : 0);
if ($mode == 'ALL') {
if ($need_uid && $this->caching_enabled) {
// Save messages index for check_cache_status()
$this->icache['all_undeleted_idx'] = $index['ALL'];
}
if ($status) {
$this->set_folder_stats($mailbox, 'cnt', $count);
$this->set_folder_stats($mailbox, 'maxuid', is_array($index) ? $index['MAX'] : 0);
}
}
}
else {
@ -3646,45 +3657,43 @@ class rcube_imap
$cache_count = count($cache_index);
// empty mailbox
if (!$msg_count)
if (!$msg_count) {
return $cache_count ? -2 : 1;
}
if ($cache_count == $msg_count) {
if ($this->skip_deleted) {
$h_index = $this->conn->fetchHeaderIndex($mailbox, "1:*", 'UID', $this->skip_deleted);
// Save index in internal cache, will be used when syncing the cache
$this->icache['folder_index'] = $h_index;
if (empty($h_index))
return -2;
if (sizeof($h_index) == $cache_count) {
$cache_index = array_flip($cache_index);
foreach ($h_index as $idx => $uid)
unset($cache_index[$uid]);
if (empty($cache_index))
return 1;
}
return -2;
if (!empty($this->icache['all_undeleted_idx'])) {
$uids = rcube_imap_generic::uncompressMessageSet($this->icache['all_undeleted_idx']);
$uids = array_flip($uids);
foreach ($cache_index as $uid) {
unset($uids[$uid]);
}
}
else {
// get all undeleted messages excluding cached UIDs
$uids = $this->search_once($mailbox, 'ALL UNDELETED NOT UID '.
rcube_imap_generic::compressMessageSet($cache_index));
}
if (empty($uids)) {
return 1;
}
} else {
// get UID of the message with highest index
$uid = $this->_id2uid($msg_count, $mailbox);
$cache_uid = array_pop($cache_index);
// uids of highest message matches -> cache seems OK
if ($cache_uid == $uid)
if ($cache_uid == $uid) {
return 1;
}
}
// cache is dirty
return -1;
}
// if cache count differs less than 10% report as dirty
else if (abs($msg_count - $cache_count) < $msg_count/10)
return -1;
else
return -2;
return (abs($msg_count - $cache_count) < $msg_count/10) ? -1 : -2;
}

@ -1008,8 +1008,8 @@ class rcube_imap_generic
}
// message IDs
if (is_array($add))
$add = $this->compressMessageSet(join(',', $add));
if (!empty($add))
$add = $this->compressMessageSet($add);
list($code, $response) = $this->execute($is_uid ? 'UID SORT' : 'SORT',
array("($field)", $encoding, 'ALL' . (!empty($add) ? ' '.$add : '')));
@ -1026,7 +1026,7 @@ class rcube_imap_generic
function fetchHeaderIndex($mailbox, $message_set, $index_field='', $skip_deleted=true, $uidfetch=false)
{
if (is_array($message_set)) {
if (!($message_set = $this->compressMessageSet(join(',', $message_set))))
if (!($message_set = $this->compressMessageSet($message_set)))
return false;
} else {
list($from_idx, $to_idx) = explode(':', $message_set);
@ -1150,12 +1150,12 @@ class rcube_imap_generic
return $result;
}
private function compressMessageSet($messages, $force=false)
static function compressMessageSet($messages, $force=false)
{
// given a comma delimited list of independent mid's,
// compresses by grouping sequences together
if (!is_array($message_set)) {
if (!is_array($messages)) {
// if less than 255 bytes long, let's not bother
if (!$force && strlen($messages)<255) {
return $messages;
@ -1199,6 +1199,23 @@ class rcube_imap_generic
return implode(',', $result);
}
static function uncompressMessageSet($messages)
{
$result = array();
$messages = explode(',', $messages);
foreach ($messages as $part) {
$items = explode(':', $part);
$max = max($items[0], $items[1]);
for ($x=$items[0]; $x<=$max; $x++) {
$result[] = $x;
}
}
return $result;
}
/**
* Returns message sequence identifier
*
@ -1265,9 +1282,6 @@ class rcube_imap_generic
return false;
}
if (is_array($message_set))
$message_set = join(',', $message_set);
$message_set = $this->compressMessageSet($message_set);
if ($add)
@ -1824,7 +1838,7 @@ class rcube_imap_generic
if (in_array('MAX', $items))
$result['MAX'] = !empty($response) ? max($response) : 0;
if (in_array('ALL', $items))
$result['ALL'] = $this->compressMessageSet(implode(',', $response), true);
$result['ALL'] = $this->compressMessageSet($response, true);
return $result;
}

Loading…
Cancel
Save