Changeset 5cf5ee6 in github


Ignore:
Timestamp:
May 18, 2011 7:48:47 AM (2 years ago)
Author:
alecpl <alec@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
b5f836e
Parents:
76d4019
Message:
  • Added general rcube_cache class with memcache support
  • Improved caching performance by skipping writes of unchanged data
  • Option enable_caching replaced by imap_cache and messages_cache options
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    ra208a4f r5cf5ee6  
    22=========================== 
    33 
     4- Added general rcube_cache class with memcache support 
     5- Improved caching performance by skipping writes of unchanged data 
     6- Option enable_caching replaced by imap_cache and messages_cache options 
    47- Add forward-as-attachment feature 
    58- jQuery-1.6.1 (#1487913, #1487144) 
  • config/main.inc.php.dist

    ra509bb6 r5cf5ee6  
    110110$rcmail_config['imap_auth_pw'] = null; 
    111111 
     112// Type of IMAP indexes cache. Supported values: 'db' and 'memcache'. 
     113$rcmail_config['imap_cache'] = null; 
     114 
     115// Enables messages cache. Only 'db' cache is supported. 
     116$rcmail_config['messages_cache'] = false; 
     117 
     118 
    112119// ---------------------------------- 
    113120// SMTP 
     
    169176// use this folder to store temp files (must be writeable for apache user) 
    170177$rcmail_config['temp_dir'] = 'temp/'; 
    171  
    172 // enable caching of messages and mailbox data in the local database. 
    173 // this is recommended if the IMAP server does not run on the same machine 
    174 $rcmail_config['enable_caching'] = false; 
    175178 
    176179// lifetime of message cache 
  • program/include/rcmail.php

    r76d4019 r5cf5ee6  
    123123  private $texts; 
    124124  private $address_books = array(); 
     125  private $caches = array(); 
    125126  private $action_map = array(); 
    126127 
     
    349350     
    350351    return $this->memcache; 
     352  } 
     353 
     354 
     355  /** 
     356   * Initialize and get cache object 
     357   * 
     358   * @param string $name Cache identifier 
     359   * @param string $type Cache type ('db' or 'memcache') 
     360   * 
     361   * @return rcube_cache Cache object 
     362   */ 
     363  public function get_cache($name, $type) 
     364  { 
     365    if (!isset($this->caches[$name])) { 
     366      $this->caches[$name] = new rcube_cache($type, $_SESSION['user_id'], $name.'.'); 
     367    } 
     368 
     369    return $this->caches[$name]; 
    351370  } 
    352371 
     
    532551      return; 
    533552 
    534     $this->imap = new rcube_imap($this->db); 
     553    $this->imap = new rcube_imap(); 
    535554    $this->imap->debug_level = $this->config->get('debug_level'); 
    536555    $this->imap->skip_deleted = $this->config->get('skip_deleted'); 
    537556 
    538557    // enable caching of imap data 
    539     if ($this->config->get('enable_caching')) { 
    540       $this->imap->set_caching(true); 
    541     } 
     558    $imap_cache = $this->config->get('imap_cache'); 
     559    $messages_cache = $this->config->get('messages_cache'); 
     560    // for backward compatybility 
     561    if ($imap_cache === null && $messages_cache === null && $this->config->get('enable_caching')) { 
     562        $imap_cache     = 'db'; 
     563        $messages_cache = true; 
     564    } 
     565    if ($imap_cache) 
     566        $this->imap->set_caching($imap_cache); 
     567    if ($messages_cache) 
     568        $this->imap->set_messages_caching(true); 
    542569 
    543570    // set pagesize from config 
     
    11171144    } 
    11181145 
     1146    foreach ($this->caches as $cache) { 
     1147        if (is_object($cache)) 
     1148            $cache->close(); 
     1149    } 
     1150 
    11191151    if (is_object($this->imap)) 
    11201152      $this->imap->close(); 
  • program/include/rcube_imap.php

    r392589e r5cf5ee6  
    5353     */ 
    5454    private $db; 
     55 
     56    /** 
     57     * Instance of rcube_cache 
     58     * 
     59     * @var rcube_cache 
     60     */ 
     61    private $cache; 
    5562    private $mailbox = 'INBOX'; 
    5663    private $delimiter = NULL; 
     
    5865    private $sort_field = ''; 
    5966    private $sort_order = 'DESC'; 
    60     private $caching_enabled = false; 
    6167    private $default_charset = 'ISO-8859-1'; 
    6268    private $struct_charset = NULL; 
    6369    private $default_folders = array('INBOX'); 
     70    private $messages_caching = false; 
    6471    private $icache = array(); 
    65     private $cache = array(); 
    66     private $cache_keys = array(); 
    67     private $cache_changes = array(); 
    6872    private $uid_id_map = array(); 
    6973    private $msg_headers = array(); 
     
    113117 
    114118    /** 
    115      * Object constructor 
    116      * 
    117      * @param object DB Database connection 
    118      */ 
    119     function __construct($db_conn) 
    120     { 
    121         $this->db = $db_conn; 
     119     * Object constructor. 
     120     */ 
     121    function __construct() 
     122    { 
    122123        $this->conn = new rcube_imap_generic(); 
    123124    } 
     
    208209    { 
    209210        $this->conn->closeConnection(); 
    210         $this->write_cache(); 
    211211    } 
    212212 
     
    707707            } 
    708708            else { 
    709                 if ($this->caching_enabled) { 
     709                if ($this->messages_caching) { 
    710710                    $keys[] = 'ALL'; 
    711711                } 
     
    723723 
    724724            if ($mode == 'ALL') { 
    725                 if ($need_uid && $this->caching_enabled) { 
     725                if ($need_uid && $this->messages_caching) { 
    726726                    // Save messages index for check_cache_status() 
    727727                    $this->icache['all_undeleted_idx'] = $index['ALL']; 
     
    839839        $cache_key    = $mailbox.'.msg'; 
    840840 
    841         if ($this->caching_enabled) { 
     841        if ($this->messages_caching) { 
    842842            // cache is OK, we can get messages from local cache 
    843843            // (assume cache is in sync when in recursive mode) 
     
    13211321 
    13221322        // Update cache 
    1323         if ($this->caching_enabled && $cache_key) { 
     1323        if ($this->messages_caching && $cache_key) { 
    13241324            // cache is incomplete? 
    13251325            $cache_index = $this->get_message_cache_index($cache_key); 
     
    21052105 
    21062106        // write structure to cache 
    2107         if ($this->caching_enabled) 
     2107        if ($this->messages_caching) 
    21082108            $this->add_message_cache($cache_key, $this->_msg_id, $headers, $struct, 
    21092109                $this->icache['message.id'][$uid], true); 
     
    25852585        if ($result) { 
    25862586            // reload message headers if cached 
    2587             if ($this->caching_enabled && !$skip_cache) { 
     2587            if ($this->messages_caching && !$skip_cache) { 
    25882588                $cache_key = $mailbox.'.msg'; 
    25892589                if ($all_mode) 
     
    34993499        $headers = array_map('strtoupper', $headers); 
    35003500 
    3501         if ($this->caching_enabled || $this->get_all_headers) 
     3501        if ($this->messages_caching || $this->get_all_headers) 
    35023502            $headers = array_merge($headers, $this->all_headers); 
    35033503 
     
    37373737 
    37383738    /** 
    3739      * Enable or disable caching 
    3740      * 
    3741      * @param boolean $set Flag 
     3739     * Enable or disable indexes caching 
     3740     * 
     3741     * @param boolean $type Cache type (memcache' or 'db') 
    37423742     * @access public 
    37433743     */ 
    3744     function set_caching($set) 
    3745     { 
    3746         if ($set && is_object($this->db)) 
    3747             $this->caching_enabled = true; 
    3748         else 
    3749             $this->caching_enabled = false; 
     3744    function set_caching($type) 
     3745    { 
     3746        if ($type) { 
     3747            $rcmail = rcmail::get_instance(); 
     3748            $this->cache = $rcmail->get_cache('IMAP', $type); 
     3749        } 
     3750        else { 
     3751            if ($this->cache) 
     3752                $this->cache->close(); 
     3753            $this->cache = null; 
     3754        } 
    37503755    } 
    37513756 
     
    37603765    function get_cache($key) 
    37613766    { 
    3762         // read cache (if it was not read before) 
    3763         if (!count($this->cache) && $this->caching_enabled) { 
    3764             return $this->_read_cache_record($key); 
    3765         } 
    3766  
    3767         return $this->cache[$key]; 
    3768     } 
    3769  
     3767        if ($this->cache) { 
     3768            return $this->cache->get($key); 
     3769        } 
     3770    } 
    37703771 
    37713772    /** 
     
    37783779    function update_cache($key, $data) 
    37793780    { 
    3780         $this->cache[$key] = $data; 
    3781         $this->cache_changed = true; 
    3782         $this->cache_changes[$key] = true; 
    3783     } 
    3784  
    3785  
    3786     /** 
    3787      * Writes the cache 
    3788      * 
    3789      * @access private 
    3790      */ 
    3791     private function write_cache() 
    3792     { 
    3793         if ($this->caching_enabled && $this->cache_changed) { 
    3794             foreach ($this->cache as $key => $data) { 
    3795                 if ($this->cache_changes[$key]) 
    3796                     $this->_write_cache_record($key, serialize($data)); 
    3797             } 
    3798         } 
    3799     } 
    3800  
     3781        if ($this->cache) { 
     3782            $this->cache->set($key, $data); 
     3783        } 
     3784    } 
    38013785 
    38023786    /** 
     
    38103794    function clear_cache($key=null, $pattern_mode=false) 
    38113795    { 
    3812         if (!$this->caching_enabled) 
    3813             return; 
    3814  
    3815         if ($key === null) { 
    3816             foreach (array_keys($this->cache) as $key) 
    3817                 $this->_clear_cache_record($key); 
    3818  
    3819             $this->cache = array(); 
    3820             $this->cache_changed = false; 
    3821             $this->cache_changes = array(); 
    3822         } 
    3823         else if ($pattern_mode) { 
    3824             foreach (array_keys($this->cache) as $k) { 
    3825                 if (preg_match($key, $k)) { 
    3826                     $this->_clear_cache_record($k); 
    3827                     $this->cache_changes[$k] = false; 
    3828                     unset($this->cache[$key]); 
    3829                 } 
    3830             } 
    3831             if (!count($this->cache)) { 
    3832                 $this->cache_changed = false; 
    3833             } 
    3834         } 
    3835         else { 
    3836             $this->_clear_cache_record($key); 
    3837             $this->cache_changes[$key] = false; 
    3838             unset($this->cache[$key]); 
    3839         } 
    3840     } 
    3841  
    3842  
    3843     /** 
    3844      * Returns cached entry 
    3845      * 
    3846      * @param string $key Cache key 
    3847      * @return mixed Cached value 
    3848      * @access private 
    3849      */ 
    3850     private function _read_cache_record($key) 
    3851     { 
    3852         if ($this->db) { 
    3853             // get cached data from DB 
    3854             $sql_result = $this->db->query( 
    3855                 "SELECT cache_id, data, cache_key ". 
    3856                 "FROM ".get_table_name('cache'). 
    3857                 " WHERE user_id=? ". 
    3858                     "AND cache_key LIKE 'IMAP.%'", 
    3859                 $_SESSION['user_id']); 
    3860  
    3861             while ($sql_arr = $this->db->fetch_assoc($sql_result)) { 
    3862                     $sql_key = preg_replace('/^IMAP\./', '', $sql_arr['cache_key']); 
    3863                 $this->cache_keys[$sql_key] = $sql_arr['cache_id']; 
    3864                     if (!isset($this->cache[$sql_key])) 
    3865                         $this->cache[$sql_key] = $sql_arr['data'] ? unserialize($sql_arr['data']) : false; 
    3866             } 
    3867         } 
    3868  
    3869         return $this->cache[$key]; 
    3870     } 
    3871  
    3872  
    3873     /** 
    3874      * Writes single cache record 
    3875      * 
    3876      * @param string $key  Cache key 
    3877      * @param mxied  $data Cache value 
    3878      * @access private 
    3879      */ 
    3880     private function _write_cache_record($key, $data) 
    3881     { 
    3882         if (!$this->db) 
    3883             return false; 
    3884  
    3885         // update existing cache record 
    3886         if ($this->cache_keys[$key]) { 
    3887             $this->db->query( 
    3888                 "UPDATE ".get_table_name('cache'). 
    3889                 " SET created=". $this->db->now().", data=? ". 
    3890                 "WHERE user_id=? ". 
    3891                 "AND cache_key=?", 
    3892                 $data, 
    3893                 $_SESSION['user_id'], 
    3894                 'IMAP.'.$key); 
    3895         } 
    3896         // add new cache record 
    3897         else { 
    3898             $this->db->query( 
    3899                 "INSERT INTO ".get_table_name('cache'). 
    3900                 " (created, user_id, cache_key, data) ". 
    3901                 "VALUES (".$this->db->now().", ?, ?, ?)", 
    3902                 $_SESSION['user_id'], 
    3903                 'IMAP.'.$key, 
    3904                 $data); 
    3905  
    3906             // get cache entry ID for this key 
    3907             $sql_result = $this->db->query( 
    3908                 "SELECT cache_id ". 
    3909                 "FROM ".get_table_name('cache'). 
    3910                 " WHERE user_id=? ". 
    3911                 "AND cache_key=?", 
    3912                 $_SESSION['user_id'], 
    3913                 'IMAP.'.$key); 
    3914  
    3915             if ($sql_arr = $this->db->fetch_assoc($sql_result)) 
    3916                 $this->cache_keys[$key] = $sql_arr['cache_id']; 
    3917         } 
    3918     } 
    3919  
    3920  
    3921     /** 
    3922      * Clears cache for single record 
    3923      * 
    3924      * @param string $ket Cache key 
    3925      * @access private 
    3926      */ 
    3927     private function _clear_cache_record($key) 
    3928     { 
    3929         $this->db->query( 
    3930             "DELETE FROM ".get_table_name('cache'). 
    3931             " WHERE user_id=? ". 
    3932             "AND cache_key=?", 
    3933             $_SESSION['user_id'], 
    3934             'IMAP.'.$key); 
    3935  
    3936         unset($this->cache_keys[$key]); 
    3937     } 
    3938  
     3796        if ($this->cache) { 
     3797            $this->cache->remove($key, $pattern_mode); 
     3798        } 
     3799    } 
    39393800 
    39403801 
     
    39443805 
    39453806    /** 
     3807     * Enable or disable messages caching 
     3808     * 
     3809     * @param boolean $set Flag 
     3810     * @access public 
     3811     */ 
     3812    function set_messages_caching($set) 
     3813    { 
     3814        $rcmail = rcmail::get_instance(); 
     3815 
     3816        if ($set && ($dbh = $rcmail->get_dbh())) { 
     3817            $this->db = $dbh; 
     3818            $this->messages_caching = true; 
     3819        } 
     3820        else { 
     3821            $this->messages_caching = false; 
     3822        } 
     3823    } 
     3824 
     3825    /** 
    39463826     * Checks if the cache is up-to-date 
    39473827     * 
     
    39523832    private function check_cache_status($mailbox, $cache_key) 
    39533833    { 
    3954         if (!$this->caching_enabled) 
     3834        if (!$this->messages_caching) 
    39553835            return -3; 
    39563836 
     
    40103890    private function get_message_cache($key, $from, $to, $sort_field, $sort_order) 
    40113891    { 
    4012         if (!$this->caching_enabled) 
     3892        if (!$this->messages_caching) 
    40133893            return NULL; 
    40143894 
     
    40553935        $internal_key = 'message'; 
    40563936 
    4057         if ($this->caching_enabled && !isset($this->icache[$internal_key][$uid])) { 
     3937        if ($this->messages_caching && !isset($this->icache[$internal_key][$uid])) { 
    40583938            $sql_result = $this->db->query( 
    40593939                "SELECT idx, headers, structure, message_id". 
     
    40893969    private function get_message_cache_index($key, $sort_field='idx', $sort_order='ASC') 
    40903970    { 
    4091         if (!$this->caching_enabled || empty($key)) 
     3971        if (!$this->messages_caching || empty($key)) 
    40923972            return NULL; 
    40933973 
     
    41444024 
    41454025        // no further caching 
    4146         if (!$this->caching_enabled) 
     4026        if (!$this->messages_caching) 
    41474027            return; 
    41484028 
     
    42114091    private function remove_message_cache($key, $ids, $idx=false) 
    42124092    { 
    4213         if (!$this->caching_enabled) 
     4093        if (!$this->messages_caching) 
    42144094            return; 
    42154095 
     
    42334113    private function clear_message_cache($key, $start_index=1) 
    42344114    { 
    4235         if (!$this->caching_enabled) 
     4115        if (!$this->messages_caching) 
    42364116            return; 
    42374117 
     
    42524132    private function get_message_cache_index_min($key, $uids=NULL) 
    42534133    { 
    4254         if (!$this->caching_enabled) 
     4134        if (!$this->messages_caching) 
    42554135            return; 
    42564136 
     
    42864166    private function get_cache_id2uid($key, $id) 
    42874167    { 
    4288         if (!$this->caching_enabled) 
     4168        if (!$this->messages_caching) 
    42894169            return null; 
    42904170 
     
    43184198    private function get_cache_uid2id($key, $uid) 
    43194199    { 
    4320         if (!$this->caching_enabled) 
     4200        if (!$this->messages_caching) 
    43214201            return null; 
    43224202 
Note: See TracChangeset for help on using the changeset viewer.