From b32cb21a7da62ea8d3eca89789f013210aa75c83 Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Tue, 23 Jun 2009 03:17:49 -0400 Subject: [PATCH] - more preformance improvements of messages caching + some code refactoring --- program/include/rcube_imap.php | 142 +++++++++++++++++++++++------------------------ 1 files changed, 70 insertions(+), 72 deletions(-) diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 76aa853..c2548c2 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -863,7 +863,6 @@ } // fetch complete message index - $msg_count = $this->_messagecount($mailbox); if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : ''))) { if ($this->sort_order == 'DESC') @@ -873,7 +872,7 @@ } else { - $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", $this->sort_field, $this->skip_deleted); + $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted); if ($this->sort_order=="ASC") asort($a_index); @@ -919,25 +918,25 @@ // other message at this position if (isset($cache_index[$id])) { - $this->remove_message_cache($cache_key, $cache_index[$id]); + $for_remove[] = $cache_index[$id]; unset($cache_index[$id]); } - $toupdate[] = $id; + $for_update[] = $id; } + // clear messages at wrong positions and those deleted that are still in cache_index + if (!empty($for_remove)) + $cache_index = array_merge($cache_index, $for_remove); + + if (!empty($cache_index)) + $this->remove_message_cache($cache_key, $cache_index); + // fetch complete headers and add to cache - if (!empty($toupdate)) { - if ($headers = iil_C_FetchHeader($this->conn, $mailbox, join(',', $toupdate), false, $this->fetch_add_headers)) + if (!empty($for_update)) { + if ($headers = iil_C_FetchHeader($this->conn, $mailbox, join(',', $for_update), false, $this->fetch_add_headers)) foreach ($headers as $header) $this->add_message_cache($cache_key, $header->id, $header); - } - - // those ids that are still in cache_index have been deleted - if (!empty($cache_index)) - { - foreach ($cache_index as $id => $uid) - $this->remove_message_cache($cache_key, $uid); } } @@ -963,7 +962,7 @@ // try search with US-ASCII charset (should be supported by server) // only if UTF-8 search is not supported - if (empty($results) && !is_array($results) && !empty($charset) && $charset!='US-ASCII') + if (empty($results) && !is_array($results) && !empty($charset) && $charset != 'US-ASCII') { // convert strings to US_ASCII if(preg_match_all('/\{([0-9]+)\}\r\n/', $str, $matches, PREG_OFFSET_CAPTURE)) @@ -984,7 +983,7 @@ else // strings for conversion not found $res = $str; - $results = $this->search($mbox_name, $res, 'US-ASCII', $sort_field); + $results = $this->search($mbox_name, $res, NULL, $sort_field); } $this->set_search_set($str, $results, $charset, $sort_field); @@ -1546,12 +1545,10 @@ $result = iil_C_Flag($this->conn, $mailbox, join(',', $uids), $flag); // reload message headers if cached - $cache_key = $mailbox.'.msg'; if ($this->caching_enabled) { - foreach ($uids as $uid) - if ($cached_headers = $this->get_cached_message($cache_key, $uid)) - $this->remove_message_cache($cache_key, $uid); + $cache_key = $mailbox.'.msg'; + $this->remove_message_cache($cache_key, $uids); // close and re-open connection // this prevents connection problems with Courier @@ -1650,15 +1647,7 @@ } // update cached message headers $cache_key = $from_mbox.'.msg'; - if ($moved && ($a_cache_index = $this->get_message_cache_index($cache_key))) - { - $start_index = 100000; - foreach ($a_uids as $uid) - { - if (($index = array_search($uid, $a_cache_index)) !== FALSE) - $start_index = min($index, $start_index); - } - + if ($moved && $start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) { // clear cache from the lowest index on $this->clear_message_cache($cache_key, $start_index); } @@ -1705,15 +1694,7 @@ // remove deleted messages from cache $cache_key = $mailbox.'.msg'; - if ($deleted && ($a_cache_index = $this->get_message_cache_index($cache_key))) - { - $start_index = 100000; - foreach ($a_uids as $uid) - { - if (($index = array_search($uid, $a_cache_index)) !== FALSE) - $start_index = min($index, $start_index); - } - + if ($deleted && $start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) { // clear cache from the lowest index on $this->clear_message_cache($cache_key, $start_index); } @@ -1963,7 +1944,7 @@ /** * Remove mailboxes from server * - * @param string Mailbox name + * @param string Mailbox name(s) string/array * @return boolean True on success */ function delete_mailbox($mbox_name) @@ -1987,9 +1968,11 @@ // send delete command to server $result = iil_C_DeleteFolder($this->conn, $mailbox); - if ($result>=0) + if ($result >= 0) { $deleted = TRUE; - + $this->clear_message_cache($mailbox.'.msg'); + } + foreach ($all_mboxes as $c_mbox) { $regex = preg_quote($mailbox . $this->delimiter, '/'); @@ -1998,18 +1981,17 @@ { iil_C_UnSubscribe($this->conn, $c_mbox); $result = iil_C_DeleteFolder($this->conn, $c_mbox); - if ($result>=0) + if ($result >= 0) { $deleted = TRUE; - } + $this->clear_message_cache($c_mbox.'.msg'); + } + } } } // clear mailboxlist cache if ($deleted) - { - $this->clear_message_cache($mailbox.'.msg'); $this->clear_cache('mailboxes'); - } return $deleted; } @@ -2059,8 +2041,7 @@ // read cache if (!isset($this->cache[$key]) && $this->caching_enabled) { - $cache_data = $this->_read_cache_record('IMAP.'.$key); - $this->cache[$key] = strlen($cache_data) ? unserialize($cache_data) : FALSE; + return $this->_read_cache_record($key); } return $this->cache[$key]; @@ -2086,7 +2067,7 @@ foreach ($this->cache as $key => $data) { if ($this->cache_changes[$key]) - $this->_write_cache_record('IMAP.'.$key, serialize($data)); + $this->_write_cache_record($key, serialize($data)); } } } @@ -2102,7 +2083,7 @@ if ($key===NULL) { foreach ($this->cache as $key => $data) - $this->_clear_cache_record('IMAP.'.$key); + $this->_clear_cache_record($key); $this->cache = array(); $this->cache_changed = FALSE; @@ -2110,7 +2091,7 @@ } else { - $this->_clear_cache_record('IMAP.'.$key); + $this->_clear_cache_record($key); $this->cache_changes[$key] = FALSE; unset($this->cache[$key]); } @@ -2121,27 +2102,25 @@ */ function _read_cache_record($key) { - $cache_data = FALSE; - if ($this->db) { // get cached data from DB $sql_result = $this->db->query( - "SELECT cache_id, data + "SELECT cache_id, data, cache_key FROM ".get_table_name('cache')." WHERE user_id=? - AND cache_key=?", - $_SESSION['user_id'], - $key); + AND cache_key LIKE 'IMAP.%'", + $_SESSION['user_id']); - if ($sql_arr = $this->db->fetch_assoc($sql_result)) + while ($sql_arr = $this->db->fetch_assoc($sql_result)) { - $cache_data = $sql_arr['data']; - $this->cache_keys[$key] = $sql_arr['cache_id']; + $sql_key = preg_replace('/^IMAP\./', '', $sql_arr['cache_key']); + $this->cache_keys[$sql_key] = $sql_arr['cache_id']; + $this->cache[$sql_key] = $sql_arr['data'] ? unserialize($sql_arr['data']) : FALSE; } } - return $cache_data; + return $this->cache[$key]; } /** @@ -2161,7 +2140,7 @@ WHERE user_id=? AND cache_key=?", $_SESSION['user_id'], - $key); + 'IMAP.'.$key); if ($sql_arr = $this->db->fetch_assoc($sql_result)) $this->cache_keys[$key] = $sql_arr['cache_id']; @@ -2179,7 +2158,7 @@ AND cache_key=?", $data, $_SESSION['user_id'], - $key); + 'IMAP.'.$key); } // add new cache record else @@ -2189,7 +2168,7 @@ (created, user_id, cache_key, data) VALUES (".$this->db->now().", ?, ?, ?)", $_SESSION['user_id'], - $key, + 'IMAP.'.$key, $data); } } @@ -2204,7 +2183,7 @@ WHERE user_id=? AND cache_key=?", $_SESSION['user_id'], - $key); + 'IMAP.'.$key); } @@ -2324,7 +2303,6 @@ $_SESSION['user_id'], $key, $uid); - if ($sql_arr = $this->db->fetch_assoc($sql_result)) { $this->cache[$internal_key][$uid] = unserialize($sql_arr['headers']); @@ -2431,19 +2409,18 @@ /** * @access private */ - function remove_message_cache($key, $uid) + function remove_message_cache($key, $uids) { if (!$this->caching_enabled) return; $this->db->query( "DELETE FROM ".get_table_name('messages')." - WHERE user_id=? - AND cache_key=? - AND uid=?", + WHERE user_id=? + AND cache_key=? + AND uid IN (".$this->db->array2list($uids, 'integer').")", $_SESSION['user_id'], - $key, - $uid); + $key); } /** @@ -2464,7 +2441,28 @@ $start_index); } + /** + * @access private + */ + function get_message_cache_index_min($key, $uids=NULL) + { + if (!$this->caching_enabled) + return; + + $sql_result = $this->db->query( + "SELECT MIN(idx) AS minidx + FROM ".get_table_name('messages')." + WHERE user_id=? + AND cache_key=?" + .(!empty($uids) ? " AND uid IN (".$this->db->array2list($uids, 'integer').")" : ''), + $_SESSION['user_id'], + $key); + if ($sql_arr = $this->db->fetch_assoc($sql_result)) + return $sql_arr['minidx']; + else + return 0; + } /* -------------------------------- @@ -2689,7 +2687,7 @@ /** - * Convert body charset to UTF-8 according to the ctype_parameters + * Convert body charset to RCMAIL_CHARSET according to the ctype_parameters * * @param string Part body to decode * @param string Charset to convert from -- Gitblit v1.9.1