Index: trunk/phase3/includes/Interwiki.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | */ |
13 | 13 | class Interwiki { |
14 | 14 | |
15 | | - // Cache - removed in LRU order when it hits limit |
| 15 | + // Cache - removes oldest entry when it hits limit |
16 | 16 | protected static $smCache = array(); |
17 | 17 | const CACHE_LIMIT = 100; // 0 means unlimited, any other value is max number of entries. |
18 | 18 | |
— | — | @@ -41,14 +41,15 @@ |
42 | 42 | if ($wgInterwikiCache) { |
43 | 43 | return Interwiki::isValidInterwikiCached( $key ); |
44 | 44 | } |
45 | | - $iw = new Interwiki; |
46 | | - if( !$iw->load( $prefix ) ){ |
47 | | - return false; |
| 45 | + $iw = Interwiki::load( $prefix ); |
| 46 | + if( !$iw ){ |
| 47 | + $iw = false; |
48 | 48 | } |
49 | 49 | if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){ |
50 | | - array_shift( self::$smCache ); |
| 50 | + reset( self::$smCache ); |
| 51 | + unset( self::$smCache[ key( self::$smCache ) ] ); |
51 | 52 | } |
52 | | - self::$smCache[$prefix] = &$iw; |
| 53 | + self::$smCache[$prefix] = $iw; |
53 | 54 | return true; |
54 | 55 | } |
55 | 56 | |
— | — | @@ -68,14 +69,15 @@ |
69 | 70 | if ($wgInterwikiCache) { |
70 | 71 | return Interwiki::getInterwikiCached( $key ); |
71 | 72 | } |
72 | | - $iw = new Interwiki; |
73 | | - if( !$iw->load( $prefix ) ){ |
74 | | - return false; |
| 73 | + $iw = Interwiki::load( $prefix ); |
| 74 | + if( !$iw ){ |
| 75 | + $iw = false; |
75 | 76 | } |
76 | 77 | if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){ |
77 | | - array_shift( self::$smCache ); |
| 78 | + reset( self::$smCache ); |
| 79 | + unset( self::$smCache[ key( self::$smCache ) ] ); |
78 | 80 | } |
79 | | - self::$smCache[$prefix] = &$iw; |
| 81 | + self::$smCache[$prefix] = $iw; |
80 | 82 | return $iw; |
81 | 83 | } |
82 | 84 | |
— | — | @@ -88,38 +90,22 @@ |
89 | 91 | * @return \type{\Interwiki} An interwiki object |
90 | 92 | */ |
91 | 93 | protected static function getInterwikiCached( $key ) { |
92 | | - global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite; |
93 | | - static $db, $site; |
94 | | - |
95 | | - if (!$db) |
96 | | - $db=dba_open($wgInterwikiCache,'r','cdb'); |
97 | | - /* Resolve site name */ |
98 | | - if ($wgInterwikiScopes>=3 and !$site) { |
99 | | - $site = dba_fetch('__sites:' . wfWikiID(), $db); |
100 | | - if ($site=="") |
101 | | - $site = $wgInterwikiFallbackSite; |
102 | | - } |
103 | | - $value = dba_fetch( wfMemcKey( $key ), $db); |
104 | | - if ($value=='' and $wgInterwikiScopes>=3) { |
105 | | - /* try site-level */ |
106 | | - $value = dba_fetch("_{$site}:{$key}", $db); |
107 | | - } |
108 | | - if ($value=='' and $wgInterwikiScopes>=2) { |
109 | | - /* try globals */ |
110 | | - $value = dba_fetch("__global:{$key}", $db); |
111 | | - } |
112 | | - if ($value=='undef') |
113 | | - $value=''; |
| 94 | + $value = getInterwikiCacheEntry( $key ); |
| 95 | + |
114 | 96 | $s = new Interwiki( $key ); |
115 | 97 | if ( $value != '' ) { |
| 98 | + // Split values |
116 | 99 | list( $local, $url ) = explode( ' ', $value, 2 ); |
117 | 100 | $s->mURL = $url; |
118 | 101 | $s->mLocal = (int)$local; |
| 102 | + }else{ |
| 103 | + $s = false; |
119 | 104 | } |
120 | 105 | if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){ |
121 | | - array_shift( self::$smCache ); |
| 106 | + reset( self::$smCache ); |
| 107 | + unset( self::$smCache[ key( self::$smCache ) ] ); |
122 | 108 | } |
123 | | - self::$smCache[$prefix] = &$s; |
| 109 | + self::$smCache[$prefix] = $s; |
124 | 110 | return $s; |
125 | 111 | } |
126 | 112 | |
— | — | @@ -132,135 +118,98 @@ |
133 | 119 | * @return \type{\bool} Whether it exists |
134 | 120 | */ |
135 | 121 | protected static function isValidInterwikiCached( $key ) { |
| 122 | + $value = getInterwikiCacheEntry( $key ); |
| 123 | + return $value != ''; |
| 124 | + } |
| 125 | + |
| 126 | + /** |
| 127 | + * Get entry from interwiki cache |
| 128 | + * |
| 129 | + * @note More logic is explained in DefaultSettings. |
| 130 | + * |
| 131 | + * @param $key \type{\string} Database key |
| 132 | + * @return \type{\string) The entry |
| 133 | + */ |
| 134 | + protected static function getInterwikiCacheEntry( $key ){ |
136 | 135 | global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite; |
137 | 136 | static $db, $site; |
138 | 137 | |
139 | | - if (!$db) |
140 | | - $db=dba_open($wgInterwikiCache,'r','cdb'); |
| 138 | + if( !$db ){ |
| 139 | + $db = dba_open( $wgInterwikiCache, 'r', 'cdb' ); |
| 140 | + } |
141 | 141 | /* Resolve site name */ |
142 | | - if ($wgInterwikiScopes>=3 and !$site) { |
143 | | - $site = dba_fetch('__sites:' . wfWikiID(), $db); |
144 | | - if ($site=="") |
| 142 | + if( $wgInterwikiScopes>=3 && !$site ) { |
| 143 | + $site = dba_fetch( '__sites:' . wfWikiID(), $db ); |
| 144 | + if ( $site == "" ){ |
145 | 145 | $site = $wgInterwikiFallbackSite; |
| 146 | + } |
146 | 147 | } |
147 | | - $value = dba_fetch( wfMemcKey( $key ), $db); |
148 | | - if ($value=='' and $wgInterwikiScopes>=3) { |
149 | | - /* try site-level */ |
150 | | - $value = dba_fetch("_{$site}:{$key}", $db); |
| 148 | + |
| 149 | + $value = dba_fetch( wfMemcKey( $key ), $db ); |
| 150 | + // Site level |
| 151 | + if ( $value == '' && $wgInterwikiScopes >= 3 ) { |
| 152 | + $value = dba_fetch( "_{$site}:{$key}", $db ); |
151 | 153 | } |
152 | | - if ($value=='' and $wgInterwikiScopes>=2) { |
153 | | - /* try globals */ |
154 | | - $value = dba_fetch("__global:{$key}", $db); |
| 154 | + // Global Level |
| 155 | + if ( $value == '' && $wgInterwikiScopes >= 2 ) { |
| 156 | + $value = dba_fetch( "__global:{$key}", $db ); |
155 | 157 | } |
156 | | - if ($value=='undef') |
157 | | - $value=''; |
158 | | - if ( $value != '' ) { |
159 | | - return true; |
160 | | - }else{ |
161 | | - return false; |
162 | | - } |
| 158 | + if ( $value == 'undef' ) |
| 159 | + $value = ''; |
| 160 | + |
| 161 | + return $value; |
163 | 162 | } |
164 | 163 | |
165 | 164 | /** |
166 | | - * Clear all member variables in the current object. Does not clear |
167 | | - * the block from the DB. |
168 | | - */ |
169 | | - function clear() { |
170 | | - $this->mURL = ''; |
171 | | - $this->mLocal = $this->mTrans = 0; |
172 | | - $this->mPrefix = null; |
173 | | - } |
174 | | - |
175 | | - /** |
176 | | - * Get the DB object |
| 165 | + * Load the interwiki, trying first memcached then the DB |
177 | 166 | * |
178 | | - * @return Database |
179 | | - */ |
180 | | - function &getDB(){ |
181 | | - $db = wfGetDB( DB_SLAVE ); |
182 | | - return $db; |
183 | | - } |
184 | | - |
185 | | - /** |
186 | | - * Load interwiki from the DB |
187 | | - * |
188 | 167 | * @param $prefix The interwiki prefix |
189 | 168 | * @return bool The prefix is valid |
| 169 | + * @static |
190 | 170 | * |
191 | 171 | */ |
192 | | - function load( $prefix ) { |
| 172 | + protected static function load( $prefix ) { |
193 | 173 | global $wgMemc; |
194 | 174 | $key = wfMemcKey( 'interwiki', $prefix ); |
195 | 175 | $mc = $wgMemc->get( $key ); |
| 176 | + $iw = false; |
196 | 177 | if( $mc && is_array( $mc ) ){ // is_array is hack for old keys |
197 | | - if( $this->loadFromArray( $mc ) ){ |
198 | | - wfDebug("Succeeded\n"); |
199 | | - return true; |
200 | | - } |
201 | | - }else{ |
202 | | - $db =& $this->getDB(); |
| 178 | + $iw = Interwiki::loadFromArray( $mc ); |
| 179 | + return $iw; |
| 180 | + } |
| 181 | + |
| 182 | + $db = wfGetDB( DB_SLAVE ); |
203 | 183 | |
204 | | - $res = $db->resultObject( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ), |
205 | | - __METHOD__ ) ); |
206 | | - if ( $this->loadFromResult( $res ) ) { |
207 | | - $mc = array( 'url' => $this->mURL, 'local' => $this->mLocal, 'trans' => $this->mTrans ); |
208 | | - $wgMemc->add( $key, $mc ); |
209 | | - return true; |
210 | | - } |
| 184 | + $row = $db->fetchRow( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ), |
| 185 | + __METHOD__ ) ); |
| 186 | + $iw = Interwiki::loadFromArray( $row ); |
| 187 | + if ( $iw ) { |
| 188 | + $mc = array( 'iw_url' => $iw->mURL, 'iw_local' => $iw->mLocal, 'iw_trans' => $iw->mTrans ); |
| 189 | + $wgMemc->add( $key, $mc ); |
| 190 | + return $iw; |
211 | 191 | } |
212 | 192 | |
213 | | - # Give up |
214 | | - $this->clear(); |
215 | 193 | return false; |
216 | 194 | } |
217 | 195 | |
218 | 196 | /** |
219 | | - * Fill in member variables from an array (e.g. memcached result) |
| 197 | + * Fill in member variables from an array (e.g. memcached result, Database::fetchRow, etc) |
220 | 198 | * |
221 | 199 | * @return bool Whether everything was there |
222 | 200 | * @param $res ResultWrapper Row from the interwiki table |
| 201 | + * @static |
223 | 202 | */ |
224 | | - function loadFromArray( $mc ) { |
225 | | - if( isset( $mc['url'] ) && isset( $mc['local'] ) && isset( $mc['trans'] ) ){ |
226 | | - $this->mURL = $mc['url']; |
227 | | - $this->mLocal = $mc['local']; |
228 | | - $this->mTrans = $mc['trans']; |
229 | | - return true; |
| 203 | + protected static function loadFromArray( $mc ) { |
| 204 | + if( isset( $mc['iw_url'] ) && isset( $mc['iw_local'] ) && isset( $mc['iw_trans'] ) ){ |
| 205 | + $iw = new Interwiki(); |
| 206 | + $iw->mURL = $mc['iw_url']; |
| 207 | + $iw->mLocal = $mc['iw_local']; |
| 208 | + $iw->mTrans = $mc['iw_trans']; |
| 209 | + return $iw; |
230 | 210 | } |
231 | 211 | return false; |
232 | 212 | } |
233 | 213 | |
234 | | - /** |
235 | | - * Fill in member variables from a result wrapper |
236 | | - * |
237 | | - * @return bool Whether there was a row there |
238 | | - * @param $res ResultWrapper Row from the interwiki table |
239 | | - */ |
240 | | - function loadFromResult( ResultWrapper $res ) { |
241 | | - $ret = false; |
242 | | - if ( 0 != $res->numRows() ) { |
243 | | - # Get first entry |
244 | | - $row = $res->fetchObject(); |
245 | | - $this->initFromRow( $row ); |
246 | | - $ret = true; |
247 | | - } |
248 | | - $res->free(); |
249 | | - return $ret; |
250 | | - } |
251 | | - |
252 | | - /** |
253 | | - * Given a database row from the interwiki table, initialize |
254 | | - * member variables |
255 | | - * |
256 | | - * @param $row ResultWrapper A row from the interwiki table |
257 | | - */ |
258 | | - function initFromRow( $row ) { |
259 | | - $this->mPrefix = $row->iw_prefix; |
260 | | - $this->mURL = $row->iw_url; |
261 | | - $this->mLocal = $row->iw_local; |
262 | | - $this->mTrans = $row->iw_trans; |
263 | | - } |
264 | | - |
265 | 214 | /** |
266 | 215 | * Get the URL for a particular title (or with $1 if no title given) |
267 | 216 | * |