00001 <?php
00010 class FileCache {
00011 var $repoGroup;
00012 var $cache = array(), $notFound = array();
00013
00014 protected static $instance;
00015
00020 static function singleton() {
00021 if ( self::$instance ) {
00022 return self::$instance;
00023 }
00024 self::$instance = new FileCache( RepoGroup::singleton() );
00025 return self::$instance;
00026 }
00027
00032 static function destroySingleton() {
00033 self::$instance = null;
00034 }
00035
00039 static function setSingleton( $instance ) {
00040 self::$instance = $instance;
00041 }
00042
00047 function __construct( $repoGroup ) {
00048 $this->repoGroup = $repoGroup;
00049 }
00050
00051
00059 function addFiles( $files ) {
00060 wfDebug( "FileCache adding ".count( $files )." files\n" );
00061 $this->cache += $files;
00062 }
00063
00070 function clearFiles( $remove ) {
00071 wfDebug( "FileCache clearing data for ".count( $remove )." files\n" );
00072 $this->cache = array_diff_keys( $this->cache, $remove );
00073 $this->notFound = array_diff_keys( $this->notFound, $remove );
00074 }
00075
00081 function markNotFound( $dbkeys ) {
00082 wfDebug( "FileCache marking ".count( $dbkeys )." files as not found\n" );
00083 $this->notFound += array_fill_keys( $dbkeys, true );
00084 }
00085
00086
00093 function findFile( $title ) {
00094 if( !( $title instanceof Title ) ) {
00095 $title = Title::makeTitleSafe( NS_FILE, $title );
00096 }
00097 if( !$title ) {
00098 return false;
00099 }
00100
00101 $dbkey = $title->getDBkey();
00102 if( array_key_exists( $dbkey, $this->cache ) ) {
00103 wfDebug( "FileCache HIT for $dbkey\n" );
00104 return $this->cache[$dbkey];
00105 }
00106 if( array_key_exists( $dbkey, $this->notFound ) ) {
00107 wfDebug( "FileCache negative HIT for $dbkey\n" );
00108 return false;
00109 }
00110
00111
00112 $file = $this->repoGroup->findFile( $title );
00113 if( $file ) {
00114 wfDebug( "FileCache MISS for $dbkey\n" );
00115 $this->cache[$dbkey] = $file;
00116 } else {
00117 wfDebug( "FileCache negative MISS for $dbkey\n" );
00118 $this->notFound[$dbkey] = true;
00119 }
00120 return $file;
00121 }
00122
00128 function findFiles( $titles ) {
00129 $titleObjs = array();
00130 foreach ( $titles as $title ) {
00131 if ( !( $title instanceof Title ) ) {
00132 $title = Title::makeTitleSafe( NS_FILE, $title );
00133 }
00134 if ( $title ) {
00135 $titleObjs[$title->getDBkey()] = $title;
00136 }
00137 }
00138
00139 $result = array_intersect_key( $this->cache, $titleObjs );
00140
00141 $unsure = array_diff_key( $titleObjs, $result, $this->notFound );
00142 if( $unsure ) {
00143 wfDebug( "FileCache MISS for ".count( $unsure )." files out of ".count( $titleObjs )."...\n" );
00144
00145
00146
00147 $found = $this->repoGroup->findFiles( $unsure );
00148 $result += $found;
00149 $this->addFiles( $found );
00150 $this->markNotFound( array_keys( array_diff_key( $unsure, $found ) ) );
00151 }
00152
00153 wfDebug( "FileCache found ".count( $result )." files out of ".count( $titleObjs )."\n" );
00154 return $result;
00155 }
00156 }