MediaWiki
REL1_24
|
00001 <?php 00027 abstract class BloomCache { 00029 protected $cacheID; 00030 00032 protected static $instances = array(); 00033 00038 final public static function get( $id ) { 00039 global $wgBloomFilterStores; 00040 00041 if ( !isset( self::$instances[$id] ) ) { 00042 if ( isset( $wgBloomFilterStores[$id] ) ) { 00043 $class = $wgBloomFilterStores[$id]['class']; 00044 self::$instances[$id] = new $class( $wgBloomFilterStores[$id] ); 00045 } else { 00046 wfDebug( "No bloom filter store '$id'; using EmptyBloomCache." ); 00047 return new EmptyBloomCache( array() ); 00048 } 00049 } 00050 00051 return self::$instances[$id]; 00052 } 00053 00064 public function __construct( array $config ) { 00065 $this->cacheID = $config['cacheId']; 00066 if ( !preg_match( '!^[a-zA-Z0-9-_]{1,32}$!', $this->cacheID ) ) { 00067 throw new MWException( "Cache ID '{$this->cacheID}' is invalid." ); 00068 } 00069 } 00070 00095 final public function check( $domain, $type, $member ) { 00096 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00097 00098 if ( method_exists( "BloomFilter{$type}", 'mergeAndCheck' ) ) { 00099 try { 00100 $virtualKey = "$domain:$type"; 00101 00102 $status = $this->getStatus( $virtualKey ); 00103 if ( $status == false ) { 00104 wfDebug( "Could not query virtual bloom filter '$virtualKey'." ); 00105 return null; 00106 } 00107 00108 $useFilter = call_user_func_array( 00109 array( "BloomFilter{$type}", 'mergeAndCheck' ), 00110 array( $this, $domain, $virtualKey, $status ) 00111 ); 00112 00113 if ( $useFilter ) { 00114 return ( $this->isHit( 'shared', "$virtualKey:$member" ) !== false ); 00115 } 00116 } catch ( MWException $e ) { 00117 MWExceptionHandler::logException( $e ); 00118 return true; 00119 } 00120 } 00121 00122 return true; 00123 } 00124 00133 final public function insert( $domain, $type, $members ) { 00134 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00135 00136 if ( method_exists( "BloomFilter{$type}", 'mergeAndCheck' ) ) { 00137 try { 00138 $virtualKey = "$domain:$type"; 00139 $prefixedMembers = array(); 00140 foreach ( (array)$members as $member ) { 00141 $prefixedMembers[] = "$virtualKey:$member"; 00142 } 00143 00144 return $this->add( 'shared', $prefixedMembers ); 00145 } catch ( MWException $e ) { 00146 MWExceptionHandler::logException( $e ); 00147 return false; 00148 } 00149 } 00150 00151 return true; 00152 } 00153 00162 final public function init( $key, $size = 1000000, $precision = .001 ) { 00163 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00164 00165 return $this->doInit( "{$this->cacheID}:$key", $size, min( .1, $precision ) ); 00166 } 00167 00175 final public function add( $key, $members ) { 00176 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00177 00178 return $this->doAdd( "{$this->cacheID}:$key", (array)$members ); 00179 } 00180 00194 final public function isHit( $key, $member ) { 00195 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00196 00197 return $this->doIsHit( "{$this->cacheID}:$key", $member ); 00198 } 00199 00206 final public function delete( $key ) { 00207 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00208 00209 return $this->doDelete( "{$this->cacheID}:$key" ); 00210 } 00211 00219 final public function setStatus( $virtualKey, array $values ) { 00220 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00221 00222 return $this->doSetStatus( "{$this->cacheID}:$virtualKey", $values ); 00223 } 00224 00237 final public function getStatus( $virtualKey ) { 00238 $section = new ProfileSection( get_class( $this ) . '::' . __FUNCTION__ ); 00239 00240 return $this->doGetStatus( "{$this->cacheID}:$virtualKey" ); 00241 } 00242 00249 public function getScopedLock( $virtualKey ) { 00250 return null; 00251 } 00252 00259 abstract protected function doInit( $key, $size, $precision ); 00260 00266 abstract protected function doAdd( $key, array $members ); 00267 00273 abstract protected function doIsHit( $key, $member ); 00274 00279 abstract protected function doDelete( $key ); 00280 00286 abstract protected function doSetStatus( $virtualKey, array $values ); 00287 00292 abstract protected function doGetStatus( $key ); 00293 } 00294 00295 class EmptyBloomCache extends BloomCache { 00296 public function __construct( array $config ) { 00297 parent::__construct( array( 'cacheId' => 'none' ) ); 00298 } 00299 00300 protected function doInit( $key, $size, $precision ) { 00301 return true; 00302 } 00303 00304 protected function doAdd( $key, array $members ) { 00305 return true; 00306 } 00307 00308 protected function doIsHit( $key, $member ) { 00309 return true; 00310 } 00311 00312 protected function doDelete( $key ) { 00313 return true; 00314 } 00315 00316 protected function doSetStatus( $virtualKey, array $values ) { 00317 return true; 00318 } 00319 00320 protected function doGetStatus( $virtualKey ) { 00321 return array( 'lastID' => null, 'asOfTime' => null, 'epoch' => null ) ; 00322 } 00323 }