alecpl
2010-10-29 9ae29c9525dbd878cff63d691625bb0c6f6cbf5c
- Improve performance of message cache status checking when skip_disabled=true


3 files modified
100 ■■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/include/rcube_imap.php 67 ●●●●● patch | view | raw | blame | history
program/include/rcube_imap_generic.php 32 ●●●● patch | view | raw | blame | history
CHANGELOG
@@ -57,6 +57,7 @@
- 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
-------------
program/include/rcube_imap.php
@@ -546,9 +546,14 @@
            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 @@
            $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 @@
        $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;
    }
program/include/rcube_imap_generic.php
@@ -1008,8 +1008,8 @@
        }
        // 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 @@
    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 @@
        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;
@@ -1197,6 +1197,23 @@
        // return as comma separated string
        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;
    }
    /**
@@ -1264,9 +1281,6 @@
        if (!$this->select($mailbox)) {
            return false;
        }
        if (is_array($message_set))
            $message_set = join(',', $message_set);
        $message_set = $this->compressMessageSet($message_set);
@@ -1824,7 +1838,7 @@
                    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;                    
                }