Ladsgroup has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/395811 )
Change subject: Join decomposition of ores_model table ...................................................................... Join decomposition of ores_model table It improves performance Bug: T181334 Change-Id: I39ef26b8d69a0d0dbb69086b7e732f50df8d5dd0 --- M extension.json M includes/ApiQueryORES.php M includes/Hooks.php M includes/Hooks/ApiHooksHandler.php A includes/Storage/HashModelLookup.php M includes/WatchedItemQueryServiceExtension.php M tests/phpunit/includes/Hooks/ChangesListHooksHandlerTest.php M tests/phpunit/includes/Hooks/ContributionsHookHandlerTest.php 8 files changed, 122 insertions(+), 75 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ORES refs/changes/11/395811/1 diff --git a/extension.json b/extension.json index 0310457..9d349aa 100644 --- a/extension.json +++ b/extension.json @@ -20,6 +20,7 @@ "ORES\\Range": "includes/Range.php", "ORES\\Scoring": "includes/Scoring.php", "ORES\\ThresholdLookup": "includes/ThresholdLookup.php", + "ORES\\Storage\\HashModelLookup": "includes/Storage/HashModelLookup.php", "ORES\\Storage\\ModelLookup": "includes/Storage/ModelLookup.php", "ORES\\Storage\\SqlModelLookup": "includes/Storage/SqlModelLookup.php", "ORES\\ApiQueryORES": "includes/ApiQueryORES.php", diff --git a/includes/ApiQueryORES.php b/includes/ApiQueryORES.php index 12b4764..10c8057 100644 --- a/includes/ApiQueryORES.php +++ b/includes/ApiQueryORES.php @@ -19,6 +19,7 @@ use ApiResult; use ApiQuery; use ApiQueryBase; +use MediaWiki\MediaWikiServices; /** * A query action to return meta information about ORES models and @@ -50,14 +51,12 @@ ApiResult::setArrayType( $data['models'], 'assoc' ); ApiResult::setIndexedTagName( $data['namespaces'], 'ns' ); - $this->addTables( 'ores_model' ); - $this->addFields( [ 'oresm_name', 'oresm_version', 'oresm_is_current' ] ); - $this->addWhere( [ 'oresm_is_current' => 1 ] ); - $res = $this->select( __METHOD__ ); + $models = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' ) + ->getModels(); - foreach ( $res as $row ) { - $data['models'][$row->oresm_name] = [ - 'version' => $row->oresm_version, + foreach ( $models as $modelName => $modelData ) { + $data['models'][$modelName] = [ + 'version' => $modelData['version'], ]; } diff --git a/includes/Hooks.php b/includes/Hooks.php index cdb8c59..a24c0cd 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -356,17 +356,15 @@ ); } - $tables["ores_${type}_mdl"] = 'ores_model'; + $modelId = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' )->getModelId( + $type + ); $tables["ores_${type}_cls"] = 'ores_classification'; $fields["ores_${type}_score"] = "ores_${type}_cls.oresc_probability"; - $join_conds["ores_${type}_mdl"] = [ 'LEFT JOIN', [ - "ores_${type}_mdl.oresm_is_current" => 1, - "ores_${type}_mdl.oresm_name" => $type, - ] ]; $join_conds["ores_${type}_cls"] = [ 'LEFT JOIN', [ - "ores_${type}_cls.oresc_model = ores_${type}_mdl.oresm_id", + "ores_${type}_cls.oresc_model = ${modelId}", "$revIdField = ores_${type}_cls.oresc_rev", "ores_${type}_cls.oresc_class" => 1 ] ]; diff --git a/includes/Hooks/ApiHooksHandler.php b/includes/Hooks/ApiHooksHandler.php index 87d2f63..9a6ee57 100644 --- a/includes/Hooks/ApiHooksHandler.php +++ b/includes/Hooks/ApiHooksHandler.php @@ -30,6 +30,7 @@ use DeferredUpdates; use JobQueueGroup; use MediaWiki\Logger\LoggerFactory; +use MediaWiki\MediaWikiServices; use ORES\Cache; use ORES\FetchScoreJob; use ORES\Hooks; @@ -137,7 +138,6 @@ $threshold = Hooks::getThreshold( 'damaging', $module->getUser(), $module->getTitle() ); $dbr = \wfGetDB( DB_REPLICA ); - $tables[] = 'ores_model'; $tables[] = 'ores_classification'; if ( isset( $show['oresreview'] ) ) { @@ -158,11 +158,10 @@ ], $dbr::LIST_OR ); } - $joinConds['ores_model'] = [ $join, - 'oresm_name = ' . $dbr->addQuotes( 'damaging' ) . ' AND oresm_is_current = 1' - ]; + $modelId = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' ) + ->getModelId( 'damaging' ); $joinConds['ores_classification'] = [ $join, - "$field = oresc_rev AND oresc_model = oresm_id AND oresc_class = 1" + "$field = oresc_rev AND oresc_model = {$modelId} AND oresc_class = 1" ]; } } @@ -258,15 +257,20 @@ $needsContinuation = false; $scores = []; + $modelData = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' ) + ->getModels(); + $modelIds = []; + foreach ( $modelData as $modelName => $modelDatum ) { + $modelIds[] = $modelDatum['id']; + } // Load cached score data $dbr = \wfGetDB( DB_REPLICA ); $res2 = $dbr->select( - [ 'ores_classification', 'ores_model' ], - [ 'oresc_rev', 'oresc_class', 'oresc_probability', 'oresm_name' ], + [ 'ores_classification' ], + [ 'oresc_rev', 'oresc_class', 'oresc_probability' ], [ 'oresc_rev' => $revids, - 'oresc_model = oresm_id', - 'oresm_is_current' => 1, + 'oresc_model' => $modelIds, ], __METHOD__ ); @@ -327,14 +331,8 @@ } ); $models = []; - $res2 = $dbr->select( - [ 'ores_model' ], - [ 'oresm_id', 'oresm_name' ], - [ 'oresm_is_current' => 1 ], - __METHOD__ - ); - foreach ( $res2 as $row ) { - $models[(int)$row->oresm_id] = $row->oresm_name; + foreach ( $modelData as $modelName => $modelDatum ) { + $models[$modelDatum['id']] = $modelName; } foreach ( $loadedScores as $revid => $data ) { diff --git a/includes/Storage/HashModelLookup.php b/includes/Storage/HashModelLookup.php new file mode 100644 index 0000000..76fcfc4 --- /dev/null +++ b/includes/Storage/HashModelLookup.php @@ -0,0 +1,70 @@ +<?php +/** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace ORES\Storage; + +use InvalidArgumentException; + +class HashModelLookup implements ModelLookup { + + private $modelData = null; + + public function __construct( array $modelData ) { + $this->modelData = $modelData; + } + + /** + * @see ModelLookup::getModelId() + * @param string $model + * + * @throws InvalidArgumentException + * @return int + */ + public function getModelId( $model ) { + $modelData = $this->modelData; + if ( !array_key_exists( $model, $modelData ) ) { + throw new InvalidArgumentException( "No model available for [{$model}]" ); + } + + return $modelData[$model]['id']; + } + + /** + * @see ModelLookup::getModelVersion() + * @param string $model + * + * @throws InvalidArgumentException + * @return string + */ + public function getModelVersion( $model ) { + $modelData = $this->modelData; + if ( !array_key_exists( $model, $modelData ) ) { + throw new InvalidArgumentException( "No model available for [{$model}]" ); + } + + return $modelData[$model]['version']; + } + + /** + * @see ModelLookup::getModels() + * + * @return array[] + */ + public function getModels() { + return $this->modelData; + } + +} diff --git a/includes/WatchedItemQueryServiceExtension.php b/includes/WatchedItemQueryServiceExtension.php index 99de1ae..71bd18c 100644 --- a/includes/WatchedItemQueryServiceExtension.php +++ b/includes/WatchedItemQueryServiceExtension.php @@ -18,6 +18,7 @@ namespace ORES; +use MediaWiki\MediaWikiServices; use ORES\Hooks\ApiHooksHandler; use ResultWrapper; use User; @@ -80,11 +81,10 @@ ], $db::LIST_OR ); } - $joinConds['ores_model'] = [ $join, - 'oresm_name = ' . $db->addQuotes( 'damaging' ) . ' AND oresm_is_current = 1' - ]; + $modelId = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' ) + ->getModelId( 'damaging' ); $joinConds['ores_classification'] = [ $join, - "rc_this_oldid = oresc_rev AND oresc_model = oresm_id AND oresc_class = 1" + "rc_this_oldid = oresc_rev AND oresc_model = {$modelId} AND oresc_class = 1" ]; } } diff --git a/tests/phpunit/includes/Hooks/ChangesListHooksHandlerTest.php b/tests/phpunit/includes/Hooks/ChangesListHooksHandlerTest.php index aacafdf..5baf4d2 100644 --- a/tests/phpunit/includes/Hooks/ChangesListHooksHandlerTest.php +++ b/tests/phpunit/includes/Hooks/ChangesListHooksHandlerTest.php @@ -8,7 +8,9 @@ use FauxRequest; use FormOptions; use IContextSource; +use MediaWiki\MediaWikiServices; use ORES\Hooks\ChangesListHooksHandler; +use ORES\Storage\HashModelLookup; use RCCacheEntry; use RecentChange; use RequestContext; @@ -38,6 +40,12 @@ 'wgOresWikiId' => 'testwiki', ] ); + $modelData = [ + 'reverted' => [ 'id' => 2, 'version' => '0.0.1' ], + 'damaging' => [ 'id' => 5, 'version' => '0.0.2' ], + 'goodfaith' => [ 'id' => 7, 'version' => '0.0.3' ], + ]; + $this->setService( 'ORESModelLookup', new HashModelLookup( $modelData ) ); $this->user = static::getTestUser()->getUser(); $this->user->setOption( 'ores-enabled', 1 ); $this->user->setOption( 'rcOresDamagingPref', 'maybebad' ); @@ -76,6 +84,7 @@ 'wgUser' => $this->user, 'wgOresModels' => $modelConfig ] ); + $tables = []; $fields = []; $conds = []; @@ -109,22 +118,15 @@ [ 'damaging' => true, 'goodfaith' => false ], [ 'tables' => [ - 'ores_damaging_mdl' => 'ores_model', 'ores_damaging_cls' => 'ores_classification' ], 'fields' => [ 'ores_damaging_score' => 'ores_damaging_cls.oresc_probability', ], 'join_conds' => [ - 'ores_damaging_mdl' => [ 'LEFT JOIN', - [ - 'ores_damaging_mdl.oresm_is_current' => 1, - 'ores_damaging_mdl.oresm_name' => 'damaging' - ] - ], 'ores_damaging_cls' => [ 'LEFT JOIN', [ - 'ores_damaging_cls.oresc_model = ores_damaging_mdl.oresm_id', + 'ores_damaging_cls.oresc_model = 5', 'rc_this_oldid = ores_damaging_cls.oresc_rev', 'ores_damaging_cls.oresc_class' => 1 ] @@ -136,22 +138,15 @@ [ 'damaging' => false, 'goodfaith' => true ], [ 'tables' => [ - 'ores_goodfaith_mdl' => 'ores_model', 'ores_goodfaith_cls' => 'ores_classification' ], 'fields' => [ 'ores_goodfaith_score' => 'ores_goodfaith_cls.oresc_probability', ], 'join_conds' => [ - 'ores_goodfaith_mdl' => [ 'LEFT JOIN', - [ - 'ores_goodfaith_mdl.oresm_is_current' => 1, - 'ores_goodfaith_mdl.oresm_name' => 'goodfaith' - ] - ], 'ores_goodfaith_cls' => [ 'LEFT JOIN', [ - 'ores_goodfaith_cls.oresc_model = ores_goodfaith_mdl.oresm_id', + 'ores_goodfaith_cls.oresc_model = 7', 'rc_this_oldid = ores_goodfaith_cls.oresc_rev', 'ores_goodfaith_cls.oresc_class' => 1 ] @@ -163,9 +158,7 @@ [ 'damaging' => true, 'goodfaith' => true ], [ 'tables' => [ - 'ores_damaging_mdl' => 'ores_model', 'ores_damaging_cls' => 'ores_classification', - 'ores_goodfaith_mdl' => 'ores_model', 'ores_goodfaith_cls' => 'ores_classification' ], 'fields' => [ @@ -173,28 +166,16 @@ 'ores_goodfaith_score' => 'ores_goodfaith_cls.oresc_probability', ], 'join_conds' => [ - 'ores_damaging_mdl' => [ 'LEFT JOIN', - [ - 'ores_damaging_mdl.oresm_is_current' => 1, - 'ores_damaging_mdl.oresm_name' => 'damaging' - ] - ], 'ores_damaging_cls' => [ 'LEFT JOIN', [ - 'ores_damaging_cls.oresc_model = ores_damaging_mdl.oresm_id', + 'ores_damaging_cls.oresc_model = 5', 'rc_this_oldid = ores_damaging_cls.oresc_rev', 'ores_damaging_cls.oresc_class' => 1 ] ], - 'ores_goodfaith_mdl' => [ 'LEFT JOIN', - [ - 'ores_goodfaith_mdl.oresm_is_current' => 1, - 'ores_goodfaith_mdl.oresm_name' => 'goodfaith' - ] - ], 'ores_goodfaith_cls' => [ 'LEFT JOIN', [ - 'ores_goodfaith_cls.oresc_model = ores_goodfaith_mdl.oresm_id', + 'ores_goodfaith_cls.oresc_model = 7', 'rc_this_oldid = ores_goodfaith_cls.oresc_rev', 'ores_goodfaith_cls.oresc_class' => 1 ] diff --git a/tests/phpunit/includes/Hooks/ContributionsHookHandlerTest.php b/tests/phpunit/includes/Hooks/ContributionsHookHandlerTest.php index 9d01a50..67b473e 100644 --- a/tests/phpunit/includes/Hooks/ContributionsHookHandlerTest.php +++ b/tests/phpunit/includes/Hooks/ContributionsHookHandlerTest.php @@ -5,6 +5,7 @@ use ContribsPager; use IContextSource; use ORES\Hooks\ContributionsHooksHandler; +use ORES\Storage\HashModelLookup; use RequestContext; use SpecialPage; use User; @@ -31,6 +32,13 @@ ], 'wgOresWikiId' => 'testwiki', ] ); + + $modelData = [ + 'reverted' => [ 'id' => 2, 'version' => '0.0.1' ], + 'damaging' => [ 'id' => 5, 'version' => '0.0.2' ], + 'goodfaith' => [ 'id' => 7, 'version' => '0.0.3' ], + ]; + $this->setService( 'ORESModelLookup', new HashModelLookup( $modelData ) ); $this->user = static::getTestUser()->getUser(); $this->user->setOption( 'ores-enabled', 1 ); @@ -62,7 +70,6 @@ public function provideOnContribsGetQueryInfo() { $expected = [ 'tables' => [ - 'ores_damaging_mdl' => 'ores_model', 'ores_damaging_cls' => 'ores_classification' ], 'fields' => [ @@ -71,17 +78,10 @@ ], 'conds' => [], 'join_conds' => [ - 'ores_damaging_mdl' => [ - 'LEFT JOIN', - [ - 'ores_damaging_mdl.oresm_is_current' => 1, - 'ores_damaging_mdl.oresm_name' => 'damaging' - ] - ], 'ores_damaging_cls' => [ 'LEFT JOIN', [ - 'ores_damaging_cls.oresc_model = ores_damaging_mdl.oresm_id', + 'ores_damaging_cls.oresc_model = 5', 'rev_id = ores_damaging_cls.oresc_rev', 'ores_damaging_cls.oresc_class' => 1 ] -- To view, visit https://gerrit.wikimedia.org/r/395811 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I39ef26b8d69a0d0dbb69086b7e732f50df8d5dd0 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/ORES Gerrit-Branch: master Gerrit-Owner: Ladsgroup <ladsgr...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits