Aleksander Machniak
2015-09-02 427ab2f3938122d7ce1d0862a583a5adaed6c6c9
Optimize folder_size() on Cyrus IMAP by using special folder annotation (#1490514)
3 files modified
60 ■■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_imap.php 56 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_storage.php 3 ●●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Optimize folder_size() on Cyrus IMAP by using special folder annotation (#1490514)
- Make optional hidding of folders with name starting with a dot - imap_skip_hidden_folders (#1490468)
- Add option to enable HTML editor always, except when replying to plain text messages (#1489365)
- Emoticons: Added option to switch on/off emoticons in compose editor (#1485732)
program/lib/Roundcube/rcube_imap.php
@@ -2427,7 +2427,7 @@
     *
     * @param mixed   $uids       Message UIDs as array or comma-separated string, or '*'
     * @param string  $flag       Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
     * @param string  $folder    Folder name
     * @param string  $folder     Folder name
     * @param boolean $skip_cache True to skip message cache clean up
     *
     * @return boolean  Operation status
@@ -3112,8 +3112,22 @@
     */
    public function folder_size($folder)
    {
        if (!strlen($folder)) {
            return false;
        }
        if (!$this->check_connection()) {
            return 0;
        }
        // On Cyrus we can use special folder annotation, which should be much faster
        if ($this->get_vendor() == 'cyrus') {
            $idx    = '/shared/vendor/cmu/cyrus-imapd/size';
            $result = $this->get_metadata($folder, $idx, array(), true);
            if (!empty($result) && is_numeric($result[$folder][$idx])) {
                return $result[$folder][$idx];
            }
        }
        // @TODO: could we try to use QUOTA here?
@@ -3879,30 +3893,33 @@
    /**
     * Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION)
     *
     * @param string $folder  Folder name (empty for server metadata)
     * @param array  $entries Entries
     * @param array  $options Command options (with MAXSIZE and DEPTH keys)
     * @param string  $folder   Folder name (empty for server metadata)
     * @param array   $entries  Entries
     * @param array   $options  Command options (with MAXSIZE and DEPTH keys)
     * @param bool    $force    Disables cache use
     *
     * @return array Metadata entry-value hash array on success, NULL on error
     * @since 0.5-beta
     */
    public function get_metadata($folder, $entries, $options=array())
    public function get_metadata($folder, $entries, $options = array(), $force = false)
    {
        $entries = (array)$entries;
        $entries = (array) $entries;
        // create cache key
        // @TODO: this is the simplest solution, but we do the same with folders list
        //        maybe we should store data per-entry and merge on request
        sort($options);
        sort($entries);
        $cache_key = 'mailboxes.metadata.' . $folder;
        $cache_key .= '.' . md5(serialize($options).serialize($entries));
        if (!$force) {
            // create cache key
            // @TODO: this is the simplest solution, but we do the same with folders list
            //        maybe we should store data per-entry and merge on request
            sort($options);
            sort($entries);
            $cache_key = 'mailboxes.metadata.' . $folder;
            $cache_key .= '.' . md5(serialize($options).serialize($entries));
        // get cached data
        $cached_data = $this->get_cache($cache_key);
            // get cached data
            $cached_data = $this->get_cache($cache_key);
        if (is_array($cached_data)) {
            return $cached_data;
            if (is_array($cached_data)) {
                return $cached_data;
            }
        }
        if (!$this->check_connection()) {
@@ -3941,7 +3958,10 @@
        }
        if (isset($res)) {
            $this->update_cache($cache_key, $res);
            if (!$force) {
                $this->update_cache($cache_key, $res);
            }
            return $res;
        }
program/lib/Roundcube/rcube_storage.php
@@ -945,10 +945,11 @@
     * @param string $folder   Folder name (empty for server metadata)
     * @param array  $entries  Entries
     * @param array  $options  Command options (with MAXSIZE and DEPTH keys)
     * @param bool   $force    Disables cache use
     *
     * @return array Metadata entry-value hash array on success, NULL on error
     */
    abstract function get_metadata($folder, $entries, $options = array());
    abstract function get_metadata($folder, $entries, $options = array(), $force = false);
    /* -----------------------------------------
     *   Cache related functions