}
/**
- * Fetch original serialized data without regard for view restrictions
+ * Get original serialized data (without checking view restrictions)
*
* @since 1.21
* @return string
*/
public function getSerializedData() {
if ( $this->mText === null ) {
+ // Revision is immutable. Load on demand.
$this->mText = $this->loadText();
}
*/
protected function getContentInternal() {
if ( $this->mContent === null ) {
- // Revision is immutable. Load on demand:
- if ( $this->mText === null ) {
- $this->mText = $this->loadText();
- }
+ $text = $this->getSerializedData();
- if ( $this->mText !== null && $this->mText !== false ) {
+ if ( $text !== null && $text !== false ) {
// Unserialize content
$handler = $this->getContentHandler();
$format = $this->getContentFormat();
- $this->mContent = $handler->unserializeContent( $this->mText, $format );
+ $this->mContent = $handler->unserializeContent( $text, $format );
}
}
*
* @return string|bool The revision's text, or false on failure
*/
- protected function loadText() {
+ private function loadText() {
// Caching may be beneficial for massive use of external storage
global $wgRevisionCacheExpiry;
static $processCache = null;
+ if ( !$wgRevisionCacheExpiry ) {
+ return $this->fetchText();
+ }
+
if ( !$processCache ) {
$processCache = new MapCacheLRU( 10 );
}
$cache = ObjectCache::getMainWANInstance();
- $textId = $this->getTextId();
- $key = wfMemcKey( 'revisiontext', 'textid', $textId );
+ $key = $cache->makeKey( 'revisiontext', 'textid', $this->getTextId() );
- if ( $wgRevisionCacheExpiry ) {
- if ( $processCache->has( $key ) ) {
- return $processCache->get( $key );
- }
- $text = $cache->get( $key );
- if ( is_string( $text ) ) {
- $processCache->set( $key, $text );
- return $text;
- }
- }
+ // No negative caching; negative hits on text rows may be due to corrupted replica DBs
+ return $processCache->getWithSetCallback( $key, function () use ( $cache, $key ) {
+ global $wgRevisionCacheExpiry;
+
+ return $cache->getWithSetCallback(
+ $key,
+ $wgRevisionCacheExpiry,
+ function () {
+ return $this->fetchText();
+ }
+ );
+ } );
+ }
+
+ private function fetchText() {
+ $textId = $this->getTextId();
// If we kept data for lazy extraction, use it now...
if ( $this->mTextRow !== null ) {
wfDebugLog( 'Revision', "No blob for text row '$textId' (revision {$this->getId()})." );
}
- # No negative caching -- negative hits on text rows may be due to corrupted replica DB servers
- if ( $wgRevisionCacheExpiry && $text !== false ) {
- $processCache->set( $key, $text );
- $cache->set( $key, $text, $wgRevisionCacheExpiry );
- }
-
- return $text;
+ return is_string( $text ) ? $text : false;
}
/**
return array_keys( $this->cache );
}
+ /**
+ * Get an item with the given key, producing and setting it if not found.
+ *
+ * If the callback returns false, then nothing is stored.
+ *
+ * @since 1.28
+ * @param string $key
+ * @param callable $callback Callback that will produce the value
+ * @return mixed The cached value if found or the result of $callback otherwise
+ */
+ public function getWithSetCallback( $key, callable $callback ) {
+ $value = $this->get( $key );
+ if ( $value === false ) {
+ $value = call_user_func( $callback );
+ if ( $value !== false ) {
+ $this->set( $key, $value );
+ }
+ }
+
+ return $value;
+ }
+
/**
* Clear one or several cache entries, or all cache entries
*