MediaWiki  REL1_19
DBABagOStuff.php
Go to the documentation of this file.
00001 <?php
00002 
00014 class DBABagOStuff extends BagOStuff {
00015         var $mHandler, $mFile, $mReader, $mWriter, $mDisabled;
00016 
00017         public function __construct( $params ) {
00018                 global $wgDBAhandler;
00019 
00020                 if ( !isset( $params['dir'] ) ) {
00021                         global $wgTmpDirectory;
00022                         $params['dir'] = $wgTmpDirectory;
00023                 }
00024 
00025                 $this->mFile = $params['dir']."/mw-cache-" . wfWikiID();
00026                 $this->mFile .= '.db';
00027                 wfDebug( __CLASS__ . ": using cache file {$this->mFile}\n" );
00028                 $this->mHandler = $wgDBAhandler;
00029         }
00030 
00038         function encode( $value, $expiry ) {
00039                 # Convert to absolute time
00040                 $expiry = $this->convertExpiry( $expiry );
00041 
00042                 return sprintf( '%010u', intval( $expiry ) ) . ' ' . serialize( $value );
00043         }
00044 
00048         function decode( $blob ) {
00049                 if ( !is_string( $blob ) ) {
00050                         return array( null, 0 );
00051                 } else {
00052                         return array(
00053                                 unserialize( substr( $blob, 11 ) ),
00054                                 intval( substr( $blob, 0, 10 ) )
00055                         );
00056                 }
00057         }
00058 
00059         function getReader() {
00060                 if ( file_exists( $this->mFile ) ) {
00061                         $handle = dba_open( $this->mFile, 'rl', $this->mHandler );
00062                 } else {
00063                         $handle = $this->getWriter();
00064                 }
00065 
00066                 if ( !$handle ) {
00067                         wfDebug( "Unable to open DBA cache file {$this->mFile}\n" );
00068                 }
00069 
00070                 return $handle;
00071         }
00072 
00073         function getWriter() {
00074                 $handle = dba_open( $this->mFile, 'cl', $this->mHandler );
00075 
00076                 if ( !$handle ) {
00077                         wfDebug( "Unable to open DBA cache file {$this->mFile}\n" );
00078                 }
00079 
00080                 return $handle;
00081         }
00082 
00083         function get( $key ) {
00084                 wfProfileIn( __METHOD__ );
00085                 wfDebug( __METHOD__ . "($key)\n" );
00086 
00087                 $handle = $this->getReader();
00088                 if ( !$handle ) {
00089                         wfProfileOut( __METHOD__ );
00090                         return null;
00091                 }
00092 
00093                 $val = dba_fetch( $key, $handle );
00094                 list( $val, $expiry ) = $this->decode( $val );
00095 
00096                 # Must close ASAP because locks are held
00097                 dba_close( $handle );
00098 
00099                 if ( !is_null( $val ) && $expiry && $expiry < time() ) {
00100                         # Key is expired, delete it
00101                         $handle = $this->getWriter();
00102                         dba_delete( $key, $handle );
00103                         dba_close( $handle );
00104                         wfDebug( __METHOD__ . ": $key expired\n" );
00105                         $val = null;
00106                 }
00107 
00108                 wfProfileOut( __METHOD__ );
00109                 return $val;
00110         }
00111 
00112         function set( $key, $value, $exptime = 0 ) {
00113                 wfProfileIn( __METHOD__ );
00114                 wfDebug( __METHOD__ . "($key)\n" );
00115 
00116                 $blob = $this->encode( $value, $exptime );
00117 
00118                 $handle = $this->getWriter();
00119                 if ( !$handle ) {
00120                         wfProfileOut( __METHOD__ );
00121                         return false;
00122                 }
00123 
00124                 $ret = dba_replace( $key, $blob, $handle );
00125                 dba_close( $handle );
00126 
00127                 wfProfileOut( __METHOD__ );
00128                 return $ret;
00129         }
00130 
00131         function delete( $key, $time = 0 ) {
00132                 wfProfileIn( __METHOD__ );
00133                 wfDebug( __METHOD__ . "($key)\n" );
00134 
00135                 $handle = $this->getWriter();
00136                 if ( !$handle ) {
00137                         wfProfileOut( __METHOD__ );
00138                         return false;
00139                 }
00140 
00141                 $ret = dba_delete( $key, $handle );
00142                 dba_close( $handle );
00143 
00144                 wfProfileOut( __METHOD__ );
00145                 return $ret;
00146         }
00147 
00148         function add( $key, $value, $exptime = 0 ) {
00149                 wfProfileIn( __METHOD__ );
00150 
00151                 $blob = $this->encode( $value, $exptime );
00152 
00153                 $handle = $this->getWriter();
00154 
00155                 if ( !$handle ) {
00156                         wfProfileOut( __METHOD__ );
00157                         return false;
00158                 }
00159 
00160                 $ret = dba_insert( $key, $blob, $handle );
00161 
00162                 # Insert failed, check to see if it failed due to an expired key
00163                 if ( !$ret ) {
00164                         list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
00165 
00166                         if ( $expiry < time() ) {
00167                                 # Yes expired, delete and try again
00168                                 dba_delete( $key, $handle );
00169                                 $ret = dba_insert( $key, $blob, $handle );
00170                                 # This time if it failed then it will be handled by the caller like any other race
00171                         }
00172                 }
00173 
00174                 dba_close( $handle );
00175 
00176                 wfProfileOut( __METHOD__ );
00177                 return $ret;
00178         }
00179 
00180         function keys() {
00181                 $reader = $this->getReader();
00182                 $k1 = dba_firstkey( $reader );
00183 
00184                 if ( !$k1 ) {
00185                         return array();
00186                 }
00187 
00188                 $result[] = $k1;
00189 
00190                 $key = dba_nextkey( $reader );
00191                 while ( $key ) {
00192                         $result[] = $key;
00193                         $key = dba_nextkey( $reader );
00194                 }
00195 
00196                 return $result;
00197         }
00198 }
00199