- 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 AJAX mode, 'noajax' property
- Plugin API: add possibility to disable plugin in framed mode, 'noframe' 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 setting IMAP flags using .SILENT suffix
- Improve performance of message cache status checking with skip_disabled=true
RELEASE 0.4.2 RELEASE 0.4.2
------------- -------------

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

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

Loading…
Cancel
Save