Mwjames has uploaded a new change for review.
https://gerrit.wikimedia.org/r/54504
Change subject: Final push to eliminate static storageData() in SMW\ParserData
......................................................................
Final push to eliminate static storageData() in SMW\ParserData
* Move stripMagicWords() out of SMW\ParserData and include it in
SMWParserExtensions::stripMagicWords where it is originally used
* Move equalDatavalues() to non-static method
Fixed a general issue in storageData() where an
array( '_MDAT', '_CDAT', '_FOO' ); would have caused a fatal
(due to bogus _FOO) and the creation of a ghost page when that
was redirected/moved.
Split up some scary spaghetti from SMWParserData:storageData() into
smaller helper methods
Double work about special properties (see SMWParserData:storageData()) is
now proper ecapsulate in addSpecialProperties().
Disable update jobs via disableUpdateJobs()
Fixed an issue where a large amount of subobjects embbeded in one page
would trigger a single job for each subobject even though
the ParserOuput and Title object for those subobjects are the same.
Static binding vs. constructor binding
SMWParseData::storeData( $output, $this->title, false ) is replaced by
$parserData = new SMW\ParserData( $title, $parserOutput );
$parserData->disableUpdateJobs();
$parserData->updateStore();
updateStore() is called from
* SMWUpdateJob::run
* SMWHooks::onLinksUpdateConstructed
* SMWHooks::onParserAfterTidy
Change-Id: I54fe629241191e141383c860d839e9e75d258add
---
M SemanticMediaWiki.hooks.php
M SemanticMediaWiki.settings.php
M includes/SMW_ParserExtensions.php
M includes/dataitems/SMW_DI_Property.php
M includes/jobs/SMW_UpdateJob.php
M includes/parserhooks/ParserData.php
6 files changed, 398 insertions(+), 48 deletions(-)
git pull
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticMediaWiki
refs/changes/04/54504/1
diff --git a/SemanticMediaWiki.hooks.php b/SemanticMediaWiki.hooks.php
index 49346c3..fcb4f89 100644
--- a/SemanticMediaWiki.hooks.php
+++ b/SemanticMediaWiki.hooks.php
@@ -438,27 +438,26 @@
* @return true
*/
public static function onParserAfterTidy( &$parser, &$text ) {
+ $cache = ObjectCache::getInstance( $GLOBALS['smwgCacheType'] );
// Separate globals from local state
+ // FIXME Do a new SMW\Settings( $GLOBALS );
$options = array(
'smwgUseCategoryHierarchy' =>
$GLOBALS['smwgUseCategoryHierarchy'],
'smwgCategoriesAsInstances' =>
$GLOBALS['smwgCategoriesAsInstances'],
);
$parserData = new SMW\ParserData( $parser->getTitle(),
$parser->getOutput(), $options );
-
- if ( !( $parserData->getData() instanceof SMWSemanticData ) ) {
- return true;
- }
-
$parserData->addCategories(
$parser->getOutput()->getCategoryLinks() );
$parserData->addDefaultSort( $parser->getDefaultSort() );
- // If an article was was marked ensure that the store is
updated as well
- if( wfGetMainCache()->get( 'smw:autorefresh:' .
$parser->getTitle()->getPrefixedDBkey() ) ){
- $parserData->storeData( true );
+ // If an article was was manually purged/moved ensure that the
store is
+ // updated as well for all other cases onLinksUpdateConstructed
will
+ // initiate the store update
+ if( $cache->get( 'smw:autorefresh:' .
$parser->getTitle()->getPrefixedDBkey() ) ){
+ $parserData->updateStore();
}
- wfGetMainCache()->delete( 'smw:autorefresh:' .
$parser->getTitle()->getPrefixedDBkey() );
+ $cache->delete( 'smw:autorefresh:' .
$parser->getTitle()->getPrefixedDBkey() );
return true;
}
@@ -479,7 +478,7 @@
*/
public static function onLinksUpdateConstructed( $linksUpdate ) {
$parserData = new SMW\ParserData( $linksUpdate->getTitle(),
$linksUpdate->getParserOutput() );
- $parserData->storeData( true );
+ $parserData->updateStore();
return true;
}
@@ -522,7 +521,7 @@
* @return true
*/
public static function onArticlePurge( &$wikiPage ) {
- wfGetMainCache()->set(
+ ObjectCache::getInstance( $GLOBALS['smwgCacheType'] )->set(
'smw:autorefresh:' .
$wikiPage->getTitle()->getPrefixedDBkey(),
$GLOBALS['smwgAutoRefreshOnPurge']
);
@@ -549,7 +548,7 @@
* @return true
*/
public static function onTitleMoveComplete( &$oldTitle, &$newTitle,
&$user, $oldId, $newId ) {
- wfGetMainCache()->set(
+ ObjectCache::getInstance( $GLOBALS['smwgCacheType'] )->set(
'smw:autorefresh:' . $newTitle->getPrefixedDBkey(),
$GLOBALS['smwgAutoRefreshOnPageMove']
);
@@ -565,6 +564,8 @@
* Fetch additional information that is related to the saving that has
just happened,
* e.g. regarding the last edit date. In runs where this hook is not
triggered, the
* last DB entry (of MW) will be used to fill such properties.
+ *
+ * Called from LocalFile.php, SpecialImport.php, Article.php, Title.php
*
* @see
http://www.mediawiki.org/wiki/Manual:Hooks/NewRevisionFromEditComplete
*
@@ -587,6 +588,7 @@
return true;
}
+ // FIXME Do a new SMW\Settings( $GLOBALS );
$options = array(
'smwgPageSpecialProperties' =>
$GLOBALS['smwgPageSpecialProperties']
);
diff --git a/SemanticMediaWiki.settings.php b/SemanticMediaWiki.settings.php
index 793dcd7..36fc19c 100644
--- a/SemanticMediaWiki.settings.php
+++ b/SemanticMediaWiki.settings.php
@@ -530,8 +530,19 @@
##
###
+# Sets Semantic MediaWiki object cache and is used to track temporary
+# changes in SMW
+#
+# @see http://www.mediawiki.org/wiki/$wgMainCacheType
+#
+# @since 1.9
+##
+$smwgCacheType = CACHE_ANYTHING;
+##
+
+###
# Sets whether or not to refresh semantic data in the store when a page is
-# manually purged (requires $wgMainCacheType to be set)
+# manually purged (requires $smwgCacheType be set)
#
# @since 1.9
##
@@ -540,7 +551,7 @@
###
# Sets whether or not to refresh semantic data in the store when a page was
-# moved (requires $wgMainCacheType to be set)
+# moved (requires $smwgCacheType be set)
#
# @since 1.9
##
diff --git a/includes/SMW_ParserExtensions.php
b/includes/SMW_ParserExtensions.php
index 4fe2c73..989ce6b 100644
--- a/includes/SMW_ParserExtensions.php
+++ b/includes/SMW_ParserExtensions.php
@@ -2,10 +2,10 @@
/**
* Static class to collect all functions related to parsing wiki text in SMW.
* It includes all parser function declarations and hooks.
- *
+ *
* @file SMW_ParserExtensions.php
* @ingroup SMW
- *
+ *
* @author Markus Krötzsch
* @author Denny Vrandecic
*/
@@ -29,7 +29,7 @@
static public function onInternalParseBeforeLinks( Parser &$parser,
&$text ) {
global $smwgStoreAnnotations, $smwgLinksInValues;
- SMWParseData::stripMagicWords( $text, $parser );
+ SMWParserExtensions::stripMagicWords( $text, $parser );
// Store the results if enabled (we have to parse them in any
case,
// in order to clean the wiki source for further processing).
@@ -39,7 +39,7 @@
// Process redirects, if any (it seems that there is indeed no
more direct way of getting this info from MW)
if ( $smwgStoreAnnotations ) {
$rt = Title::newFromRedirect( $text );
-
+
if ( !is_null( $rt ) ) {
$p = new SMWDIProperty( '_REDI' );
$di = SMWDIWikiPage::newFromTitle( $rt, '__red'
);
@@ -178,4 +178,35 @@
return $result;
}
+ /**
+ * Remove relevant SMW magic words from the given text and return
+ * an array of the names of all discovered magic words. Moreover,
+ * store this array in the current parser output, using the variable
+ * mSMWMagicWords.
+ *
+ * @note moved from SMWParseData::stripMagicWords as it is only used
+ * in here
+ *
+ * @since 1.9
+ */
+ static public function stripMagicWords( &$text, Parser $parser ) {
+ $words = array();
+ $mw = MagicWord::get( 'SMW_NOFACTBOX' );
+
+ if ( $mw->matchAndRemove( $text ) ) {
+ $words[] = 'SMW_NOFACTBOX';
+ }
+
+ $mw = MagicWord::get( 'SMW_SHOWFACTBOX' );
+
+ if ( $mw->matchAndRemove( $text ) ) {
+ $words[] = 'SMW_SHOWFACTBOX';
+ }
+
+ $output = $parser->getOutput();
+ $output->mSMWMagicWords = $words;
+
+ return $words;
+ }
+
}
diff --git a/includes/dataitems/SMW_DI_Property.php
b/includes/dataitems/SMW_DI_Property.php
index f011e92..47f5337 100644
--- a/includes/dataitems/SMW_DI_Property.php
+++ b/includes/dataitems/SMW_DI_Property.php
@@ -23,7 +23,7 @@
// Property improper value data item ID
const TYPE_ERROR = '_ERRP';
// Property instance of a category
- const TYPE_CATEGORY_INSTANCE = '_INST';
+ const TYPE_CATEGORY = '_INST';
// Property "subcategory of"
const TYPE_SUBCATEGORY = '_SUBC';
// Property sort key of a page
@@ -36,6 +36,10 @@
const TYPE_LAST_EDITOR = '_LEDT';
// Property "is a new page"
const TYPE_NEW_PAGE = '_NEWP';
+ // Property "has type"
+ const TYPE_HAS_TYPE = '_TYPE';
+ // Property "corresponds to"
+ const TYPE_CONVERSION = '_CONV';
/**
* Array for assigning types to predefined properties. Each
@@ -373,12 +377,12 @@
// Properties without translation cannot be entered by or
// displayed to users, whatever their "show" value below.
SMWDIProperty::$m_prop_types = array(
- '_TYPE' => array( '__typ', true ), // "has
type"
+ self::TYPE_HAS_TYPE => array( '__typ', true ),
// "has type"
'_URI' => array( '__spu', true ), //
"equivalent URI"
- self::TYPE_CATEGORY_INSTANCE => array(
'__sin', false ), // instance of a category
+ self::TYPE_CATEGORY => array( '__sin', false
), // instance of a category
'_UNIT' => array( '__sps', true ), //
"displays unit"
'_IMPO' => array( '__imp', true ), //
"imported from"
- '_CONV' => array( '__sps', true ), //
"corresponds to"
+ self::TYPE_CONVERSION => array( '__sps', true
), // "corresponds to"
'_SERV' => array( '__sps', true ), //
"provides service"
'_PVAL' => array( '__sps', true ), // "allows
value"
'_REDI' => array( '__red', true ), //
redirects to some page
diff --git a/includes/jobs/SMW_UpdateJob.php b/includes/jobs/SMW_UpdateJob.php
index 361732e..42693b4 100644
--- a/includes/jobs/SMW_UpdateJob.php
+++ b/includes/jobs/SMW_UpdateJob.php
@@ -28,6 +28,17 @@
}
/**
+ * Returns Title object
+ *
+ * @since 1.9
+ *
+ * @return \Title
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
* Run job
* @return boolean success
*/
@@ -61,11 +72,15 @@
wfProfileOut( __METHOD__ . '-parse' );
wfProfileIn( __METHOD__ . '-update' );
- SMWParseData::storeData( $output, $this->title, false );
-
+ // @since 1.9
+ // SMWParseData::storeData( $output, $this->title, false );
+ $parserData = new SMW\ParserData( $this->title, $output );
+ $parserData->disableUpdateJobs();
+ $parserData->updateStore();
+
wfProfileOut( __METHOD__ . '-update' );
wfProfileOut( 'SMWUpdateJob::run (SMW)' );
-
+
return true;
}
@@ -81,5 +96,5 @@
parent::insert();
}
}
-
+
}
diff --git a/includes/parserhooks/ParserData.php
b/includes/parserhooks/ParserData.php
index 0ce28e0..c5d6106 100644
--- a/includes/parserhooks/ParserData.php
+++ b/includes/parserhooks/ParserData.php
@@ -6,7 +6,9 @@
use WikiPage;
use ParserOutput;
use MWException;
+use Job;
+use SMWStore;
use SMWDIWikiPage;
use SMWPropertyValue;
use SMWSemanticData;
@@ -15,6 +17,7 @@
use SMWDIBlob;
use SMWDIBoolean;
use SMWDITime;
+use SMWUpdateJob;
/**
* Interface handling semantic data storage to a ParserOutput instance
@@ -90,11 +93,11 @@
public function clearData();
/**
- * Stores semantic data to the database
+ * Updates the store with semantic data fetched from a ParserOutput
object
*
* @since 1.9
*/
- public function storeData( $runAsJob );
+ public function updateStore();
/**
* Returns an report about activities that occurred during processing
@@ -150,6 +153,12 @@
protected $options;
/**
+ * Represents invoked $smwgEnableUpdateJobs
+ * @var $updateJobs
+ */
+ protected $updateJobs = true;
+
+ /**
* Allows explicitly to switch storage method, MW 1.21 comes with a new
* method setExtensionData/getExtensionData in how the ParserOutput
* stores arbitrary data
@@ -174,6 +183,7 @@
$this->title = $title;
$this->parserOutput = $parserOutput;
$this->options = $options;
+ $this->updateJobs = $GLOBALS['smwgEnableUpdateJobs'];
$this->setData();
}
@@ -255,6 +265,16 @@
}
/**
+ * Explicitly disable update jobs (e.g when running store update
+ * in the job queue)
+ *
+ * @since 1.9
+ */
+ public function disableUpdateJobs() {
+ $this->updateJobs = false;
+ }
+
+ /**
* Returns instantiated semanticData container
*
* @since 1.9
@@ -284,18 +304,6 @@
*/
public function clearData() {
$this->semanticData = new SMWSemanticData( $this->getSubject()
);
- }
-
- /**
- * Stores semantic data to the database
- *
- * @since 1.9
- *
- * @param boolean $runAsJob
- */
- public function storeData( $runAsJob = true ) {
- // FIXME get rid of the static method
- \SMWParseData::storeData( $this->getOutput(),
$this->getTitle(), $runAsJob );
}
/**
@@ -388,6 +396,8 @@
* from parser output, so that they are also replicated in SMW for more
* efficient querying.
*
+ * @see SMWHooks::onParserAfterTidy
+ *
* @since 1.9
*
* @param array $categoryLinks
@@ -403,7 +413,7 @@
foreach ( $categoryLinks as $catname ) {
if ( $this->options['smwgCategoriesAsInstances'] && (
$this->getTitle()->getNamespace() !== NS_CATEGORY ) ) {
$this->semanticData->addPropertyObjectValue(
- new SMWDIProperty(
SMWDIProperty::TYPE_CATEGORY_INSTANCE ),
+ new SMWDIProperty(
SMWDIProperty::TYPE_CATEGORY ),
new SMWDIWikiPage( $catname,
NS_CATEGORY, '' )
);
}
@@ -419,6 +429,8 @@
/**
* Add default sort
+ *
+ * @see SMWHooks::onParserAfterTidy
*
* @since 1.9
*
@@ -455,15 +467,15 @@
return true;
}
- // Keeps temporary account on processed properties
+ // Keeps temporary account over processed properties
$processedProperty = array();
foreach ( $this->options['smwgPageSpecialProperties'] as
$propertyId ) {
// Ensure that only special properties are added that
are registered
// and only added once
- if ( SMWDIProperty::getPredefinedPropertyTypeId(
$propertyId ) === '' &&
- array_key_exists( $propertyId,
$processedProperty ) ) {
+ if ( ( SMWDIProperty::getPredefinedPropertyTypeId(
$propertyId ) === '' ) ||
+ ( array_key_exists( $propertyId,
$processedProperty ) ) ) {
continue;
}
@@ -472,7 +484,6 @@
// Don't do a double round
if ( $this->semanticData->getPropertyValues(
$propertyDI ) !== array() ) {
$processedProperty[ $propertyId ] = true;
- //var_dump( __METHOD__, 'check double',
$propertyDI->getLabel() );
continue;
}
@@ -491,16 +502,292 @@
$dataValue = new SMWDIBoolean(
$revision->getParentId() !== '' );
break;
case SMWDIProperty::TYPE_LAST_EDITOR :
- //$revision = Revision::newFromTitle(
$title );
- //$user = User::newFromId(
$revision->getUser() );
$dataValue =
SMWDIWikiPage::newFromTitle( $user->getUserPage() );
break;
}
- if ( $dataValue instanceof SMWDataItem ) {
+ if ( is_a( $dataValue, 'SMWDataItem' ) ) {
$processedProperty[ $propertyId ] = true;
$this->semanticData->addPropertyObjectValue(
$propertyDI, $dataValue );
}
}
}
+
+ /**
+ * Updates the store with semantic data attached to a ParserOutput
object
+ *
+ * This function takes care of storing the collected semantic data and
takes
+ * care of clearing out any outdated entries for the processed page. It
assume that
+ * parsing has happened and that all relevant data is contained in the
provided parser
+ * output.
+ *
+ * Optionally, this function also takes care of triggering indirect
updates that might be
+ * needed for overall database consistency. If the saved page describes
a property or data type,
+ * the method checks whether the property type, the data type, the
allowed values, or the
+ * conversion factors have changed. If so, it triggers SMWUpdateJobs
for the relevant articles,
+ * which then asynchronously update the semantic data in the database.
+ *
+ * @todo FIXME: Some job generations here might create too many jobs at
once
+ * on a large wiki. Use incremental jobs instead.
+ *
+ * To disable jobs either set $smwgEnableUpdateJobs = false or invoke
+ * SMW\ParserData::disableUpdateJobs()
+ *
+ * Called from SMWUpdateJob::run, SMWHooks::onLinksUpdateConstructed,
+ * SMWHooks::onParserAfterTidy
+ *
+ * @since 1.9
+ *
+ * @return boolean
+ */
+ public function updateStore() {
+ wfProfileIn( __METHOD__ );
+
+ // FIXME get rid of globals and use options array instead while
+ // invoking the constructor
+ $this->options = array(
+ 'smwgDeclarationProperties' =>
$GLOBALS['smwgDeclarationProperties'],
+ 'smwgPageSpecialProperties' =>
$GLOBALS['smwgPageSpecialProperties']
+ );
+
+ $namespace = $this->title->getNamespace();
+ $wikiPage = WikiPage::factory( $this->title );
+ $revision = $wikiPage->getRevision();
+ $store = smwfGetStore();
+ $jobs = array();
+
+ // Make sure to have a valid revision (null means delete etc.)
+ // Check if semantic data should be processed and displayed for
a page in
+ // the given namespace
+ $processSemantics = $revision !== null ?
smwfIsSemanticsProcessed( $namespace ) : false;
+
+ if ( $processSemantics ) {
+ $user = \User::newFromId( $revision->getUser() );
+ $this->addSpecialProperties( $wikiPage, $revision,
$user );
+ } else {
+ // data found, but do all operations as if it was empty
+ $this->semanticData = new SMWSemanticData(
$this->getSubject() );
+ }
+
+ // Careful: storage access must happen *before* the storage
update;
+ // even finding uses of a property fails after its type was
changed.
+ if ( $this->updateJobs && ( $namespace === SMW_NS_PROPERTY ) ) {
+ $this->getDiffPropertyTypes( $store, $jobs );
+ } else if ( $this->updateJobs && ( $namespace === SMW_NS_TYPE )
) {
+ $this->getDiffConversionFactors( $store, $jobs );
+ }
+
+ // Actually store semantic data, or at least clear it if needed
+ if ( $processSemantics ) {
+ $store->updateData( $this->semanticData );
+ } else {
+ $store->clearData( $this->semanticData->getSubject() );
+ }
+
+ // Job::batchInsert was deprecated in MW 1.21
+ // @see JobQueueGroup::singleton()->push( $job );
+ if ( $jobs !== array() ) {
+ Job::batchInsert( $jobs );
+ }
+
+ wfProfileOut( __METHOD__ );
+
+ return true;
+ }
+
+ /**
+ * Helper method to handle diff/change in type property pages
+ *
+ * @note If it is a property, then we need to check if the type or the
+ * allowed values have been changed.
+ *
+ * @since 1.9
+ *
+ * @param SMWStore $store
+ * @param array &$jobs
+ */
+ protected function getDiffPropertyTypes( SMWStore $store, array &$jobs
) {
+ wfProfileIn( __METHOD__ );
+
+ $updatejobflag = false;
+ $ptype = new SMWDIProperty( SMWDIProperty::TYPE_HAS_TYPE );
+
+ // Get values from the store
+ $oldtype = $store->getPropertyValues(
+ $this->semanticData->getSubject(),
+ $ptype
+ );
+
+ // Get values currently hold by the semantic container
+ $newtype = $this->semanticData->getPropertyValues( $ptype );
+
+ // Compare old and new type
+ if ( !$this->equalDatavalues( $oldtype, $newtype ) ) {
+ $updatejobflag = true;
+ } else {
+ // Compare values (in case of _PVAL (allowed values)
for a
+ // property change must be processed again)
+ foreach ( $this->options['smwgDeclarationProperties']
as $prop ) {
+
+ $dataItem = new SMWDIProperty( $prop );
+ $oldValues = $store->getPropertyValues(
+ $this->semanticData->getSubject(),
+ $dataItem
+ );
+ $newValues =
$this->semanticData->getPropertyValues( $dataItem );
+ $updatejobflag = !$this->equalDatavalues(
$oldValues, $newValues );
+ }
+ }
+
+ // Job generation
+ if ( $updatejobflag ) {
+ $prop = new SMWDIProperty( $this->title->getDBkey() );
+
+ // Array of all subjects that have some value for the
given property
+ $subjects = $store->getAllPropertySubjects( $prop );
+
+ // Add jobs
+ $this->addJobs( $subjects, $jobs );
+
+ // Hook
+ wfRunHooks( 'smwUpdatePropertySubjects', array( &$jobs
) );
+
+ // Fetch all those that have an error property attached
and
+ // re-run it through the job-queue
+ $subjects = $store->getPropertySubjects(
+ new SMWDIProperty( SMWDIProperty::TYPE_ERROR ),
+ $this->semanticData->getSubject()
+ );
+
+ // Add jobs
+ $this->addJobs( $subjects, $jobs );
+ }
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Helper method to handle diff/change of conversion related properties
+ *
+ * @note if it is a type we need to check if the conversion factors
+ * have been changed
+ *
+ * @since 1.9
+ *
+ * @param SMWStore $store
+ * @param array &$jo
+ */
+ protected function getDiffConversionFactors( SMWStore $store, array
&$jobs ) {
+ wfProfileIn( __METHOD__ );
+
+ $updatejobflag = false;
+ $pconv = new SMWDIProperty( SMWDIProperty::TYPE_CONVERSION );
+ $ptype = new SMWDIProperty( SMWDIProperty::TYPE_HAS_TYPE );
+
+ $oldfactors = smwfGetStore()->getPropertyValues(
+ $this->semanticData->getSubject(),
+ $pconv
+ );
+ $newfactors = $this->semanticData->getPropertyValues( $pconv );
+
+ // Compare
+ $updatejobflag = !$this->equalDatavalues( $oldfactors,
$newfactors );
+
+ // Job generation
+ if ( $updatejobflag ) {
+
+ /// FIXME: this will kill large wikis! Use incremental
updates!
+ $dataValue = SMWDataValueFactory::newTypeIdValue(
'__typ', $title->getDBkey() );
+ $propertyPages = $store->getPropertySubjects( $ptype,
$dataValue );
+
+ foreach ( $propertyPages as $propertyPage ) {
+ // Add jobs
+ $this->addJobs( array( $propertyPage ), $jobs );
+
+ $prop = new SMWDIProperty(
$propertyPage->getDBkey() );
+ $subjects = $store->getAllPropertySubjects(
$prop );
+
+ // Add jobs
+ $this->addJobs( $subjects, $jobs );
+
+ $subjects = $store->getPropertySubjects(
+ new SMWDIProperty(
SMWDIProperty::TYPE_ERROR ),
+ $prop->getWikiPageValue()
+ );
+
+ // Add jobs
+ $this->addJobs( $subjects, $jobs );
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * Helper method to iterate over an array of SMWDIWikiPage and return
and
+ * array of SMWUpdateJob jobs
+ *
+ * Check whether a job with the same getPrefixedDBkey string (prefixed
title,
+ * with underscores and any interwiki and namespace prefixes) is already
+ * registered and if so don't insert a new job. This is particular
important
+ * for pages that include a large amount of subobjects where the same
Title
+ * and ParserOutput object is used (subobjects are included using the
same
+ * WikiPage which means the resulting ParserOutput object is the same)
+ *
+ * @since 1.9
+ *
+ * @param SMWDIWikiPage[] $subjects
+ * @param array &$jobs
+ */
+ protected function addJobs( array $subjects, &$jobs ) {
+
+ foreach ( $subjects as $subject ) {
+ $duplicate = false;
+ $subjectTitle = $subject->getTitle();
+
+ if ( $subjectTitle instanceof Title ) {
+
+ // Avoid duplicate jobs for the same title
object
+ foreach ( $jobs as $job ) {
+ if (
$job->getTitle()->getPrefixedDBkey() === $subjectTitle->getPrefixedDBkey() ){
+ $duplicate = true;
+ break;
+ }
+ }
+ if ( !$duplicate ) {
+ $jobs[] = new SMWUpdateJob(
$subjectTitle );
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper function that compares two arrays of data values to check
whether
+ * they contain the same content. Returns true if the two arrays
contain the
+ * same data values (irrespective of their order), false otherwise.
+ *
+ * @since 1.9
+ */
+ protected function equalDatavalues( $oldDataValue, $newDataValue ) {
+ // The hashes of all values of both arrays are taken, then
sorted
+ // and finally concatenated, thus creating one long hash out of
each
+ // of the data value arrays. These are compared.
+ $values = array();
+ foreach ( $oldDataValue as $v ) {
+ $values[] = $v->getHash();
+ }
+
+ sort( $values );
+ $oldDataValueHash = implode( '___', $values );
+
+ $values = array();
+ foreach ( $newDataValue as $v ) {
+ $values[] = $v->getHash();
+ }
+
+ sort( $values );
+ $newDataValueHash = implode( '___', $values );
+
+ return ( $oldDataValueHash == $newDataValueHash );
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/54504
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I54fe629241191e141383c860d839e9e75d258add
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits