Changeset 5082 in subversion


Ignore:
Timestamp:
Aug 17, 2011 5:15:53 AM (21 months ago)
Author:
alec
Message:
  • Improve performance (minimize number of sql queries) in situation when a message is changed few times in one request (using some kind of auto-save and internal cache)
Location:
branches/devel-mcache/roundcubemail/program/include
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/devel-mcache/roundcubemail/program/include/rcube_imap.php

    r5052 r5082  
    221221    { 
    222222        $this->conn->closeConnection(); 
     223        if ($this->mcache) 
     224            $this->mcache->close(); 
    223225    } 
    224226 
     
    20082010 
    20092011        $headers->structure = $struct; 
    2010  
    2011         // update cached headers with structure 
    2012         if ($mcache = $this->get_mcache_engine()) { 
    2013             $mcache->add_message($mailbox, $headers); 
    2014         } 
    20152012 
    20162013        return $this->icache['message'] = $headers; 
  • branches/devel-mcache/roundcubemail/program/include/rcube_imap_cache.php

    r5047 r5082  
    7777 
    7878 
     79    /** 
     80     * Cleanup actions (on shutdown). 
     81     */ 
    7982    public function close() 
    8083    { 
     84        $this->save_icache(); 
     85        $this->icache = null; 
    8186    } 
    8287 
     
    328333    function get_message($mailbox, $uid) 
    329334    { 
     335        // Check internal cache 
     336        if (($message = $this->icache['message']) 
     337            && $message['mailbox'] == $mailbox && $message['object']->uid == $uid 
     338        ) { 
     339            return $this->icache['message']['object']; 
     340        } 
     341 
    330342        $flag_fields = implode(', ', array_map(array($this->db, 'quoteIdentifier'), $this->flag_fields)); 
    331343 
     
    348360        if (empty($message)) { 
    349361            $message = $this->imap->get_headers($uid, $mailbox, true); 
    350             // update cache 
    351             $this->add_message($mailbox, $message, !$found); 
     362            // cache will be updated in close(), see below 
     363        } 
     364 
     365        // Save the message in internal cache, will be written to DB in close() 
     366        // Common scenario: user opens unseen message 
     367        // - get message (SELECT) 
     368        // - set message headers/structure (INSERT or UPDATE) 
     369        // - set \Seen flag (UPDATE) 
     370        // This way we can skip one UPDATE 
     371        if (!empty($message)) { 
     372            // Save current message from internal cache 
     373            $this->save_icache(); 
     374 
     375            $this->icache['message'] = array( 
     376                'object'  => $message, 
     377                'mailbox' => $mailbox, 
     378                'exists'  => $found, 
     379                'md5sum'  => md5(serialize($message)), 
     380            ); 
    352381        } 
    353382 
     
    408437     * 
    409438     * @param string  $mailbox  Folder name 
    410      * @param array   $uids     Message UIDs or -1 to change flag 
     439     * @param array   $uids     Message UIDs or null to change flag 
    411440     *                          of all messages in a folder 
    412441     * @param string  $flag     The name of the flag 
     
    418447 
    419448        if (in_array($flag, $this->flag_fields)) { 
     449            // Internal cache update 
     450            if ($uids && count($uids) == 1 && ($uid = current($uids)) 
     451                && ($message = $this->icache['message']) 
     452                && $message['mailbox'] == $mailbox && $message['object']->uid == $uid 
     453            ) { 
     454                $message['object']->$flag = $enabled; 
     455                return; 
     456            } 
     457 
    420458            $this->db->query( 
    421459                "UPDATE ".get_table_name('cache_messages') 
     
    449487        } 
    450488        else { 
     489            // Remove the message from internal cache 
     490            if (!empty($uids) && !is_array($uids) && ($message = $this->icache['message']) 
     491                && $message['mailbox'] == $mailbox && $message['object']->uid == $uids 
     492            ) { 
     493                $this->icache['message'] = null; 
     494            } 
     495 
    451496            $this->db->query( 
    452497                "DELETE FROM ".get_table_name('cache_messages') 
     
    823868        } 
    824869    } 
     870 
     871 
     872    /** 
     873     * Saves message stored in internal cache 
     874     */ 
     875    private function save_icache() 
     876    { 
     877        // Save current message from internal cache 
     878        if ($message = $this->icache['message']) { 
     879            $object = $message['object']; 
     880            // remove body too big (>500kB) 
     881            if ($object->body && strlen($object->body) > 500 * 1024) 
     882                $object->body = null; 
     883 
     884            // calculate current md5 sum 
     885            $md5sum = md5(serialize($object)); 
     886 
     887            if ($message['md5sum'] != $md5sum) { 
     888                $this->add_message($message['mailbox'], $object, !$message['exists']); 
     889            } 
     890 
     891            $this->icache['message']['md5sum'] = $md5sum; 
     892        } 
     893    } 
     894 
    825895} 
Note: See TracChangeset for help on using the changeset viewer.