Optimize folder_size() on Cyrus IMAP by using special folder annotation (#1490514)

pull/294/head
Aleksander Machniak 9 years ago
parent 5eb9c70b60
commit 427ab2f393

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail 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) - 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) - 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) - Emoticons: Added option to switch on/off emoticons in compose editor (#1485732)

@ -2427,7 +2427,7 @@ class rcube_imap extends rcube_storage
* *
* @param mixed $uids Message UIDs as array or comma-separated string, or '*' * @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 $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 * @param boolean $skip_cache True to skip message cache clean up
* *
* @return boolean Operation status * @return boolean Operation status
@ -3112,10 +3112,24 @@ class rcube_imap extends rcube_storage
*/ */
public function folder_size($folder) public function folder_size($folder)
{ {
if (!strlen($folder)) {
return false;
}
if (!$this->check_connection()) { if (!$this->check_connection()) {
return 0; 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? // @TODO: could we try to use QUOTA here?
$result = $this->conn->fetchHeaderIndex($folder, '1:*', 'SIZE', false); $result = $this->conn->fetchHeaderIndex($folder, '1:*', 'SIZE', false);
@ -3879,30 +3893,33 @@ class rcube_imap extends rcube_storage
/** /**
* Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION) * Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION)
* *
* @param string $folder Folder name (empty for server metadata) * @param string $folder Folder name (empty for server metadata)
* @param array $entries Entries * @param array $entries Entries
* @param array $options Command options (with MAXSIZE and DEPTH keys) * @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 * @return array Metadata entry-value hash array on success, NULL on error
* @since 0.5-beta * @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 if (!$force) {
// @TODO: this is the simplest solution, but we do the same with folders list // create cache key
// maybe we should store data per-entry and merge on request // @TODO: this is the simplest solution, but we do the same with folders list
sort($options); // maybe we should store data per-entry and merge on request
sort($entries); sort($options);
$cache_key = 'mailboxes.metadata.' . $folder; sort($entries);
$cache_key .= '.' . md5(serialize($options).serialize($entries)); $cache_key = 'mailboxes.metadata.' . $folder;
$cache_key .= '.' . md5(serialize($options).serialize($entries));
// get cached data // get cached data
$cached_data = $this->get_cache($cache_key); $cached_data = $this->get_cache($cache_key);
if (is_array($cached_data)) { if (is_array($cached_data)) {
return $cached_data; return $cached_data;
}
} }
if (!$this->check_connection()) { if (!$this->check_connection()) {
@ -3941,7 +3958,10 @@ class rcube_imap extends rcube_storage
} }
if (isset($res)) { if (isset($res)) {
$this->update_cache($cache_key, $res); if (!$force) {
$this->update_cache($cache_key, $res);
}
return $res; return $res;
} }

@ -945,10 +945,11 @@ abstract class rcube_storage
* @param string $folder Folder name (empty for server metadata) * @param string $folder Folder name (empty for server metadata)
* @param array $entries Entries * @param array $entries Entries
* @param array $options Command options (with MAXSIZE and DEPTH keys) * @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 * @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 * Cache related functions

Loading…
Cancel
Save