Index: trunk/phase3/includes/BagOStuff.php |
— | — | @@ -191,7 +191,7 @@ |
192 | 192 | } |
193 | 193 | |
194 | 194 | function get($key) { |
195 | | - if(!$this->bag[$key]) |
| 195 | + if( !isset( $this->bag[$key] ) ) |
196 | 196 | return false; |
197 | 197 | if($this->_expire($key)) |
198 | 198 | return false; |
— | — | @@ -203,7 +203,7 @@ |
204 | 204 | } |
205 | 205 | |
206 | 206 | function delete($key,$time=0) { |
207 | | - if(!$this->bag[$key]) |
| 207 | + if( !isset( $this->bag[$key] ) ) |
208 | 208 | return false; |
209 | 209 | unset($this->bag[$key]); |
210 | 210 | return true; |
Index: trunk/phase3/includes/GlobalFunctions.php |
— | — | @@ -2809,16 +2809,12 @@ |
2810 | 2810 | * Get an ASCII string identifying this wiki |
2811 | 2811 | * This is used as a prefix in memcached keys |
2812 | 2812 | */ |
2813 | | -function wfWikiID( $db = null ) { |
2814 | | - if( $db instanceof Database ) { |
2815 | | - return $db->getWikiID(); |
2816 | | - } else { |
| 2813 | +function wfWikiID() { |
2817 | 2814 | global $wgDBprefix, $wgDBname; |
2818 | | - if ( $wgDBprefix ) { |
2819 | | - return "$wgDBname-$wgDBprefix"; |
2820 | | - } else { |
2821 | | - return $wgDBname; |
2822 | | - } |
| 2815 | + if ( $wgDBprefix ) { |
| 2816 | + return "$wgDBname-$wgDBprefix"; |
| 2817 | + } else { |
| 2818 | + return $wgDBname; |
2823 | 2819 | } |
2824 | 2820 | } |
2825 | 2821 | |
Index: trunk/phase3/includes/filerepo/LocalFile.php |
— | — | @@ -133,11 +133,12 @@ |
134 | 134 | } |
135 | 135 | |
136 | 136 | /** |
137 | | - * Get the memcached key |
| 137 | + * Get the memcached key for the main data for this file, or false if |
| 138 | + * there is no access to the shared cache. |
138 | 139 | */ |
139 | 140 | function getCacheKey() { |
140 | 141 | $hashedName = md5($this->getName()); |
141 | | - return wfMemcKey( 'file', $hashedName ); |
| 142 | + return $this->repo->getSharedCacheKey( 'file', $hashedName ); |
142 | 143 | } |
143 | 144 | |
144 | 145 | /** |
— | — | @@ -590,8 +591,10 @@ |
591 | 592 | function purgeHistory() { |
592 | 593 | global $wgMemc; |
593 | 594 | $hashedName = md5($this->getName()); |
594 | | - $oldKey = wfMemcKey( 'oldfile', $hashedName ); |
595 | | - $wgMemc->delete( $oldKey ); |
| 595 | + $oldKey = $this->getSharedCacheKey( 'oldfile', $hashedName ); |
| 596 | + if ( $oldKey ) { |
| 597 | + $wgMemc->delete( $oldKey ); |
| 598 | + } |
596 | 599 | } |
597 | 600 | |
598 | 601 | /** |
Index: trunk/phase3/includes/filerepo/ForeignDBFile.php |
— | — | @@ -19,16 +19,6 @@ |
20 | 20 | return $file; |
21 | 21 | } |
22 | 22 | |
23 | | - function getCacheKey() { |
24 | | - if ( $this->repo->hasSharedCache() ) { |
25 | | - $hashedName = md5($this->name); |
26 | | - return wfForeignMemcKey( $this->repo->dbName, $this->repo->tablePrefix, |
27 | | - 'file', $hashedName ); |
28 | | - } else { |
29 | | - return false; |
30 | | - } |
31 | | - } |
32 | | - |
33 | 23 | function publish( $srcPath, $flags = 0 ) { |
34 | 24 | $this->readOnlyError(); |
35 | 25 | } |
Index: trunk/phase3/includes/filerepo/ForeignDBViaLBRepo.php |
— | — | @@ -27,6 +27,21 @@ |
28 | 28 | return $this->hasSharedCache; |
29 | 29 | } |
30 | 30 | |
| 31 | + /** |
| 32 | + * Get a key on the primary cache for this repository. |
| 33 | + * Returns false if the repository's cache is not accessible at this site. |
| 34 | + * The parameters are the parts of the key, as for wfMemcKey(). |
| 35 | + */ |
| 36 | + function getSharedCacheKey( /*...*/ ) { |
| 37 | + if ( $this->hasSharedCache() ) { |
| 38 | + $args = func_get_args(); |
| 39 | + array_unshift( $args, $this->wiki ); |
| 40 | + return implode( ':', $args ); |
| 41 | + } else { |
| 42 | + return false; |
| 43 | + } |
| 44 | + } |
| 45 | + |
31 | 46 | function store( $srcPath, $dstZone, $dstRel, $flags = 0 ) { |
32 | 47 | throw new MWException( get_class($this) . ': write operations are not supported' ); |
33 | 48 | } |
Index: trunk/phase3/includes/filerepo/FileRepo.php |
— | — | @@ -545,15 +545,19 @@ |
546 | 546 | |
547 | 547 | /** |
548 | 548 | * Invalidates image redirect cache related to that image |
549 | | - * |
| 549 | + * Doesn't do anything for repositories that don't support image redirects. |
| 550 | + * |
| 551 | + * STUB |
550 | 552 | * @param Title $title Title of image |
551 | 553 | */ |
552 | | - function invalidateImageRedirect( $title ) { |
553 | | - global $wgMemc; |
554 | | - $memcKey = $this->getMemcKey( "image_redirect:" . md5( $title->getPrefixedDBkey() ) ); |
555 | | - $wgMemc->delete( $memcKey ); |
556 | | - } |
| 554 | + function invalidateImageRedirect( $title ) {} |
557 | 555 | |
| 556 | + /** |
| 557 | + * Get an array or iterator of file objects for files that have a given |
| 558 | + * SHA-1 content hash. |
| 559 | + * |
| 560 | + * STUB |
| 561 | + */ |
558 | 562 | function findBySha1( $hash ) { |
559 | 563 | return array(); |
560 | 564 | } |
— | — | @@ -574,16 +578,25 @@ |
575 | 579 | return wfMsg( 'shared-repo' ); |
576 | 580 | } |
577 | 581 | |
578 | | - function getSlaveDB() { |
579 | | - return wfGetDB( DB_SLAVE ); |
| 582 | + /** |
| 583 | + * Get a key on the primary cache for this repository. |
| 584 | + * Returns false if the repository's cache is not accessible at this site. |
| 585 | + * The parameters are the parts of the key, as for wfMemcKey(). |
| 586 | + * |
| 587 | + * STUB |
| 588 | + */ |
| 589 | + function getSharedCacheKey( /*...*/ ) { |
| 590 | + return false; |
580 | 591 | } |
581 | 592 | |
582 | | - function getMasterDB() { |
583 | | - return wfGetDB( DB_MASTER ); |
| 593 | + /** |
| 594 | + * Get a key for this repo in the local cache domain. These cache keys are |
| 595 | + * not shared with remote instances of the repo. |
| 596 | + * The parameters are the parts of the key, as for wfMemcKey(). |
| 597 | + */ |
| 598 | + function getLocalCacheKey( /*...*/ ) { |
| 599 | + $args = func_get_args(); |
| 600 | + array_unshift( $args, 'filerepo', $this->getName() ); |
| 601 | + return call_user_func_array( 'wfMemcKey', $args ); |
584 | 602 | } |
585 | | - |
586 | | - function getMemcKey( $key ) { |
587 | | - return wfWikiID( $this->getSlaveDB() ) . ":{$key}"; |
588 | | - } |
589 | | - |
590 | 603 | } |
Index: trunk/phase3/includes/filerepo/ForeignAPIRepo.php |
— | — | @@ -114,7 +114,7 @@ |
115 | 115 | 'action' => 'query' ) ) ); |
116 | 116 | |
117 | 117 | if( !isset( $this->mQueryCache[$url] ) ) { |
118 | | - $key = wfMemcKey( 'ForeignAPIRepo', 'Metadata', md5( $url ) ); |
| 118 | + $key = $this->getLocalCacheKey( 'ForeignAPIRepo', 'Metadata', md5( $url ) ); |
119 | 119 | $data = $wgMemc->get( $key ); |
120 | 120 | if( !$data ) { |
121 | 121 | $data = Http::get( $url ); |
— | — | @@ -176,7 +176,7 @@ |
177 | 177 | return $this->getThumbUrl( $name, $width, $height ); |
178 | 178 | } |
179 | 179 | |
180 | | - $key = wfMemcKey( 'ForeignAPIRepo', 'ThumbUrl', $name ); |
| 180 | + $key = $this->getLocalCacheKey( 'ForeignAPIRepo', 'ThumbUrl', $name ); |
181 | 181 | if ( $thumbUrl = $wgMemc->get($key) ) { |
182 | 182 | wfDebug("Got thumb from local cache. $thumbUrl \n"); |
183 | 183 | return $thumbUrl; |
Index: trunk/phase3/includes/filerepo/File.php |
— | — | @@ -1077,7 +1077,7 @@ |
1078 | 1078 | if ( $renderUrl ) { |
1079 | 1079 | if ( $this->repo->descriptionCacheExpiry > 0 ) { |
1080 | 1080 | wfDebug("Attempting to get the description from cache..."); |
1081 | | - $key = wfMemcKey( 'RemoteFileDescription', 'url', $wgContLang->getCode(), |
| 1081 | + $key = $this->getLocalCacheKey( 'RemoteFileDescription', 'url', $wgContLang->getCode(), |
1082 | 1082 | $this->getName() ); |
1083 | 1083 | $obj = $wgMemc->get($key); |
1084 | 1084 | if ($obj) { |
Index: trunk/phase3/includes/filerepo/LocalRepo.php |
— | — | @@ -83,17 +83,24 @@ |
84 | 84 | $title = Title::makeTitle( NS_FILE, $title->getText() ); |
85 | 85 | } |
86 | 86 | |
87 | | - $memcKey = $this->getMemcKey( "image_redirect:" . md5( $title->getPrefixedDBkey() ) ); |
| 87 | + $memcKey = $this->getSharedCacheKey( 'image_redirect', md5( $title->getPrefixedDBkey() ) ); |
| 88 | + if ( $memcKey === false ) { |
| 89 | + $memcKey = $this->getLocalCacheKey( 'image_redirect', md5( $title->getPrefixedDBkey() ) ); |
| 90 | + $expiry = 300; // no invalidation, 5 minutes |
| 91 | + } else { |
| 92 | + $expiry = 86400; // has invalidation, 1 day |
| 93 | + } |
88 | 94 | $cachedValue = $wgMemc->get( $memcKey ); |
89 | | - if( $cachedValue ) { |
90 | | - return Title::newFromDbKey( $cachedValue ); |
91 | | - } elseif( $cachedValue == ' ' ) { # FIXME: ugly hack, but BagOStuff caching seems to be weird and return false if !cachedValue, not only if it doesn't exist |
| 95 | + if ( $cachedValue === ' ' || $cachedValue === '' ) { |
| 96 | + // Does not exist |
92 | 97 | return false; |
93 | | - } |
| 98 | + } elseif ( strval( $cachedValue ) !== '' ) { |
| 99 | + return Title::newFromText( $cachedValue ); |
| 100 | + } // else $cachedValue is false or null: cache miss |
94 | 101 | |
95 | 102 | $id = $this->getArticleID( $title ); |
96 | 103 | if( !$id ) { |
97 | | - $wgMemc->set( $memcKey, " ", 9000 ); |
| 104 | + $wgMemc->set( $memcKey, " ", $expiry ); |
98 | 105 | return false; |
99 | 106 | } |
100 | 107 | $dbr = $this->getSlaveDB(); |
— | — | @@ -104,12 +111,14 @@ |
105 | 112 | __METHOD__ |
106 | 113 | ); |
107 | 114 | |
108 | | - if( $row ) $targetTitle = Title::makeTitle( $row->rd_namespace, $row->rd_title ); |
109 | | - $wgMemc->set( $memcKey, ($row ? $targetTitle->getPrefixedDBkey() : " "), 9000 ); |
110 | | - if( !$row ) { |
| 115 | + if( $row ) { |
| 116 | + $targetTitle = Title::makeTitle( $row->rd_namespace, $row->rd_title ); |
| 117 | + $wgMemc->set( $memcKey, $targetTitle->getPrefixedDBkey(), $expiry ); |
| 118 | + return $targetTitle; |
| 119 | + } else { |
| 120 | + $wgMemc->set( $memcKey, '', $expiry ); |
111 | 121 | return false; |
112 | 122 | } |
113 | | - return $targetTitle; |
114 | 123 | } |
115 | 124 | |
116 | 125 | |
— | — | @@ -134,8 +143,10 @@ |
135 | 144 | return $id; |
136 | 145 | } |
137 | 146 | |
138 | | - |
139 | | - |
| 147 | + /** |
| 148 | + * Get an array or iterator of file objects for files that have a given |
| 149 | + * SHA-1 content hash. |
| 150 | + */ |
140 | 151 | function findBySha1( $hash ) { |
141 | 152 | $dbr = $this->getSlaveDB(); |
142 | 153 | $res = $dbr->select( |
— | — | @@ -174,4 +185,42 @@ |
175 | 186 | $res->free(); |
176 | 187 | return $result; |
177 | 188 | } |
| 189 | + |
| 190 | + /** |
| 191 | + * Get a connection to the slave DB |
| 192 | + */ |
| 193 | + function getSlaveDB() { |
| 194 | + return wfGetDB( DB_SLAVE ); |
| 195 | + } |
| 196 | + |
| 197 | + /** |
| 198 | + * Get a connection to the master DB |
| 199 | + */ |
| 200 | + function getMasterDB() { |
| 201 | + return wfGetDB( DB_MASTER ); |
| 202 | + } |
| 203 | + |
| 204 | + /** |
| 205 | + * Get a key on the primary cache for this repository. |
| 206 | + * Returns false if the repository's cache is not accessible at this site. |
| 207 | + * The parameters are the parts of the key, as for wfMemcKey(). |
| 208 | + */ |
| 209 | + function getSharedCacheKey( /*...*/ ) { |
| 210 | + $args = func_get_args(); |
| 211 | + return call_user_func_array( 'wfMemcKey', $args ); |
| 212 | + } |
| 213 | + |
| 214 | + /** |
| 215 | + * Invalidates image redirect cache related to that image |
| 216 | + * |
| 217 | + * @param Title $title Title of image |
| 218 | + */ |
| 219 | + function invalidateImageRedirect( $title ) { |
| 220 | + global $wgMemc; |
| 221 | + $memcKey = $this->getSharedCacheKey( 'image_redirect', md5( $title->getPrefixedDBkey() ) ); |
| 222 | + if ( $memcKey ) { |
| 223 | + $wgMemc->delete( $memcKey ); |
| 224 | + } |
| 225 | + } |
178 | 226 | } |
| 227 | + |
Index: trunk/phase3/includes/filerepo/ForeignAPIFile.php |
— | — | @@ -162,13 +162,13 @@ |
163 | 163 | function purgeDescriptionPage() { |
164 | 164 | global $wgMemc, $wgContLang; |
165 | 165 | $url = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgContLang->getCode() ); |
166 | | - $key = wfMemcKey( 'RemoteFileDescription', 'url', md5($url) ); |
| 166 | + $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5($url) ); |
167 | 167 | $wgMemc->delete( $key ); |
168 | 168 | } |
169 | 169 | |
170 | 170 | function purgeThumbnails() { |
171 | 171 | global $wgMemc; |
172 | | - $key = wfMemcKey( 'ForeignAPIRepo', 'ThumbUrl', $this->getName() ); |
| 172 | + $key = $this->repo->getLocalCacheKey( 'ForeignAPIRepo', 'ThumbUrl', $this->getName() ); |
173 | 173 | $wgMemc->delete( $key ); |
174 | 174 | $files = $this->getThumbnails(); |
175 | 175 | $dir = $this->getThumbPath( $this->getName() ); |
Index: trunk/phase3/includes/filerepo/ForeignDBRepo.php |
— | — | @@ -44,6 +44,21 @@ |
45 | 45 | return $this->hasSharedCache; |
46 | 46 | } |
47 | 47 | |
| 48 | + /** |
| 49 | + * Get a key on the primary cache for this repository. |
| 50 | + * Returns false if the repository's cache is not accessible at this site. |
| 51 | + * The parameters are the parts of the key, as for wfMemcKey(). |
| 52 | + */ |
| 53 | + function getSharedCacheKey( /*...*/ ) { |
| 54 | + if ( $this->hasSharedCache() ) { |
| 55 | + $args = func_get_args(); |
| 56 | + array_unshift( $args, $this->dbName, $this->tablePrefix ); |
| 57 | + return call_user_func_array( 'wfForeignMemcKey', $args ); |
| 58 | + } else { |
| 59 | + return false; |
| 60 | + } |
| 61 | + } |
| 62 | + |
48 | 63 | function store( $srcPath, $dstZone, $dstRel, $flags = 0 ) { |
49 | 64 | throw new MWException( get_class($this) . ': write operations are not supported' ); |
50 | 65 | } |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -185,6 +185,7 @@ |
186 | 186 | * (bug 18173) MediaWiki now fails when unable to determine a client IP |
187 | 187 | * (bug 19170) Special:Version should follow the content language direction |
188 | 188 | * (bug 19160) maintenance/purgeOldText.inc is now compatible with PostgreSQL |
| 189 | +* Fixed performance regression in "bad image list" feature |
189 | 190 | |
190 | 191 | == API changes in 1.16 == |
191 | 192 | |