From: Michael M Slusarz Date: Fri, 20 Mar 2009 15:48:28 +0000 (-0600) Subject: Implement search (message list) caching X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=3bf96ee478d42f7b5497b2ebe78b9a47f0c67bb2;p=horde.git Implement search (message list) caching --- diff --git a/framework/Imap_Client/lib/Horde/Imap/Client/Base.php b/framework/Imap_Client/lib/Horde/Imap/Client/Base.php index c2e8e8a82..3e40c3d98 100644 --- a/framework/Imap_Client/lib/Horde/Imap/Client/Base.php +++ b/framework/Imap_Client/lib/Horde/Imap/Client/Base.php @@ -1301,7 +1301,33 @@ abstract class Horde_Imap_Client_Base } } - $ret = $this->_search($query, $options); + /* If CONDSTORE is available, we can take advantage of search result + * caching. We invalidate the cache when the MODSEQ changes. We + * store results by hashing the options array - the generated + * query is already added to '_query' key above. */ + $cache = $ret = null; + if (isset($this->_init['enabled']['CONDSTORE'])) { + ksort($options); + $cache = hash('md5', serialize($options)); + $metadata = $this->_cache->getMetaData($mailbox, array('HICsearch')); + if (isset($metadata['HICsearch'][$cache])) { + $ret = $metadata['HICsearch'][$cache]; + if ($this->_debug) { + fwrite($this->_debug, sprintf("Horde_Imap_Client: Retrieved search results from cache (mailbox: %s; id: %s)\n", $mailbox, $cache)); + } + } + } + + if (is_null($ret)) { + $ret = $this->_search($query, $options); + if ($cache) { + $metadata['HICsearch'][$cache] = $ret; + $this->_updateMetaData($mailbox, $metadata); + if ($this->_debug) { + fwrite($this->_debug, sprintf("Horde_Imap_Client: Saved search results to cache (mailbox: %s; id: %s)\n", $mailbox, $cache)); + } + } + } if (!empty($options['reverse'])) { if (empty($options['sort'])) { @@ -1319,7 +1345,8 @@ abstract class Horde_Imap_Client_Base * * @param object $query The search query. * @param array $options Additional options. The '_query' key contains - * the value of $query->build(). + * the value of $query->build(). 'sort' and + * 'reverse' should be ignored. * * @return array An array of UIDs (default) or an array of message * sequence numbers (if 'sequence' is true). @@ -1864,7 +1891,8 @@ abstract class Horde_Imap_Client_Base if (!empty($uids)) { $this->_fetch(array(Horde_Imap_Client::FETCH_FLAGS => true), array('changedsince' => $metadata['HICmodseq'], 'ids' => $uids)); } - $this->_cache->setMetaData($mailbox, array('HICmodseq' => $status_res['highestmodseq'])); + + $this->_updateMetaData($mailbox, array('HICmodseq' => $status_res['highestmodseq'])); } } @@ -2453,7 +2481,7 @@ abstract class Horde_Imap_Client_Base try { $this->_cache->set($mailbox, $tocache, $uidvalid); if ($is_flags) { - $this->_cache->setMetaData($mailbox, array('HICmodseq' => max($highestmodseq))); + $this->_updateMetaData($mailbox, array('HICmodseq' => max($highestmodseq))); } } catch (Horde_Imap_Client_Exception $e) { if ($e->getCode() != Horde_Imap_Client_Exception::CACHEUIDINVALID) { @@ -2462,4 +2490,21 @@ abstract class Horde_Imap_Client_Base } } + /** + * Update metadata entries. + * + * @param string $mailbox Mailbox to update. + * @param array $data The data to update with. + */ + protected function _updateMetaData($mailbox, $data) + { + /* If we see that HICmodseq is being updated, we know that we have + * to invalidate the search cache. */ + if (isset($data['HICmodseq']) && !isset($data['HICsearch'])) { + $data['HICsearch'] = array(); + } + + $this->_cache->setMetaData($mailbox, $data); + } + } diff --git a/framework/Imap_Client/lib/Horde/Imap/Client/Socket.php b/framework/Imap_Client/lib/Horde/Imap/Client/Socket.php index 74aecc102..e8df3ca66 100644 --- a/framework/Imap_Client/lib/Horde/Imap/Client/Socket.php +++ b/framework/Imap_Client/lib/Horde/Imap/Client/Socket.php @@ -825,7 +825,7 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base } else { /* We know the mailbox has been updated, so update the * highestmodseq metadata in the cache. */ - $this->_cache->setMetaData($mailbox, array('HICmodseq' => $this->_temp['mailbox']['highestmodseq'])); + $this->_updateMetaData($mailbox, array('HICmodseq' => $this->_temp['mailbox']['highestmodseq'])); } } elseif ($condstore) { $this->_init['enabled']['CONDSTORE'] = true; @@ -1400,7 +1400,7 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base } if (isset($this->_init['enabled']['QRESYNC'])) { - $this->_cache->setMetaData($mailbox, array('HICmodseq' => $this->_temp['mailbox']['highestmodseq'])); + $this->_updateMetaData($mailbox, array('HICmodseq' => $this->_temp['mailbox']['highestmodseq'])); } return $list_msgs ? $expunged : null;