Index: trunk/extensions/CodeReview/codereview.sql |
— | — | @@ -58,6 +58,11 @@ |
59 | 59 | -- * if the revision change only one file, the file path |
60 | 60 | -- * else, common directory for all changes (e.g. trunk/phase3/includes/ ) |
61 | 61 | cr_path varchar(255) binary, |
| 62 | + |
| 63 | + -- Text of the diff or ES url |
| 64 | + cr_diff mediumblob NULL, |
| 65 | + -- Text flags: gzip,utf-8,external |
| 66 | + cr_flags tinyblob NOT NULL, |
62 | 67 | |
63 | 68 | primary key (cr_repo_id, cr_id), |
64 | 69 | key (cr_repo_id, cr_timestamp), |
Index: trunk/extensions/CodeReview/archives/codereview-cr_diff.sql |
— | — | @@ -0,0 +1,3 @@ |
| 2 | +ALTER TABLE /*$wgDBprefix*/code_rev |
| 3 | + ADD cr_diff mediumblob NULL, |
| 4 | + ADD cr_flags tinyblob NOT NULL; |
Property changes on: trunk/extensions/CodeReview/archives/codereview-cr_diff.sql |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 5 | + native |
Index: trunk/extensions/CodeReview/CodeRepository.php |
— | — | @@ -177,16 +177,19 @@ |
178 | 178 | * 'cached' to *only* fetch if cached |
179 | 179 | */ |
180 | 180 | public function getDiff( $rev, $useCache = '' ) { |
181 | | - global $wgMemc; |
| 181 | + global $wgMemc, $wgDefaultExternalStore; |
| 182 | + wfProfileIn( __METHOD__ ); |
182 | 183 | |
183 | 184 | $rev1 = $rev - 1; |
184 | 185 | $rev2 = $rev; |
185 | 186 | |
186 | 187 | $revision = $this->getRevision( $rev ); |
187 | 188 | if( $revision == null || !$revision->isDiffable() ) { |
| 189 | + wfProfileOut( __METHOD__ ); |
188 | 190 | return false; |
189 | 191 | } |
190 | 192 | |
| 193 | + # Try memcached... |
191 | 194 | $key = wfMemcKey( 'svn', md5( $this->mPath ), 'diff', $rev1, $rev2 ); |
192 | 195 | if( $useCache === 'skipcache' ) { |
193 | 196 | $data = NULL; |
— | — | @@ -194,12 +197,65 @@ |
195 | 198 | $data = $wgMemc->get( $key ); |
196 | 199 | } |
197 | 200 | |
| 201 | + # Try the database... |
| 202 | + if( !$data ) { |
| 203 | + $dbr = wfGetDB( DB_SLAVE ); |
| 204 | + $row = $dbr->selectRow( 'code_rev', |
| 205 | + array( 'cr_diff', 'cr_flags' ), |
| 206 | + array( 'cr_repo_id' => $this->mId, 'cr_id' => $rev, 'cr_diff IS NOT NULL' ), |
| 207 | + __METHOD__ |
| 208 | + ); |
| 209 | + if( $row ) { |
| 210 | + $flags = explode( ',', $row->cr_flags ); |
| 211 | + $data = $row->cr_diff; |
| 212 | + # Use external methods for external objects, text in table is URL-only then |
| 213 | + if( in_array( 'external', $flags ) ) { |
| 214 | + $url = $data; |
| 215 | + @list(/* $proto */,$path) = explode('://',$url,2); |
| 216 | + if( $path == "" ) { |
| 217 | + $data = false; // something is wrong... |
| 218 | + } else { |
| 219 | + $data = ExternalStore::fetchFromURL($url); |
| 220 | + } |
| 221 | + } |
| 222 | + // If the text was fetched without an error, convert it |
| 223 | + if( $data !== false && in_array( 'gzip', $flags ) ) { |
| 224 | + # Deal with optional compression of archived pages. |
| 225 | + # This can be done periodically via maintenance/compressOld.php, and |
| 226 | + # as pages are saved if $wgCompressRevisions is set. |
| 227 | + $data = gzinflate( $data ); |
| 228 | + } |
| 229 | + } |
| 230 | + } |
| 231 | + |
| 232 | + # Generate the diff as needed... |
198 | 233 | if( !$data && $useCache !== 'cached' ) { |
199 | 234 | $svn = SubversionAdaptor::newFromRepo( $this->mPath ); |
200 | 235 | $data = $svn->getDiff( '', $rev1, $rev2 ); |
| 236 | + // Store to cache |
201 | 237 | $wgMemc->set( $key, $data, 3600*24*3 ); |
| 238 | + // Permanent DB storage |
| 239 | + $flags = Revision::compressRevisionText( $data ); |
| 240 | + if( ($storage = $wgDefaultExternalStore) ) { |
| 241 | + if( is_array($storage) ) { |
| 242 | + # Distribute storage across multiple clusters |
| 243 | + $store = $storage[mt_rand(0, count( $storage ) - 1)]; |
| 244 | + } else { |
| 245 | + $store = $storage; |
| 246 | + } |
| 247 | + # Store and get the URL |
| 248 | + $data = ExternalStore::insert( $store, $data ); |
| 249 | + if( $flags ) $flags .= ','; |
| 250 | + $flags .= 'external'; |
| 251 | + } |
| 252 | + $dbw = wfGetDB( DB_MASTER ); |
| 253 | + $dbw->update( 'code_rev', |
| 254 | + array( 'cr_diff' => $data, 'cr_flags' => $flags ), |
| 255 | + array( 'cr_repo_id' => $this->mId, 'cr_id' => $rev ), |
| 256 | + __METHOD__ |
| 257 | + ); |
202 | 258 | } |
203 | | - |
| 259 | + wfProfileOut( __METHOD__ ); |
204 | 260 | return $data; |
205 | 261 | } |
206 | 262 | |