From: Roan Kattouw Date: Fri, 5 May 2017 01:04:58 +0000 (-0700) Subject: ApiQueryTags: Use cached statistics instead of querying hit counts ourselves X-Git-Tag: 1.31.0-rc.0~3331^2 X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=commitdiff_plain;h=08f746478afda38fa8301c82f2ee0e5cef36aefe;p=lhc%2Fweb%2Fwiklou.git ApiQueryTags: Use cached statistics instead of querying hit counts ourselves The hit count query was quite slow. Unfortunately, it seems that we do need tagUsageStatistics() even when hitcounts are not requested, because it might list additional tags that aren't listed by the list*Tags() functions. I don't know if this can happen in practice, but all the code around tags seems to operate as if it might. Bug: T164552 Change-Id: Ifccf7f5ac7a1220ff67a68589398cbf30aefd3ad --- diff --git a/includes/api/ApiQueryTags.php b/includes/api/ApiQueryTags.php index be67dd249b..1b154faecb 100644 --- a/includes/api/ApiQueryTags.php +++ b/includes/api/ApiQueryTags.php @@ -53,37 +53,24 @@ class ApiQueryTags extends ApiQueryBase { $softwareDefinedTags = array_fill_keys( ChangeTags::listSoftwareDefinedTags(), 0 ); $explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 ); $softwareActivatedTags = array_fill_keys( ChangeTags::listSoftwareActivatedTags(), 0 ); + $tagStats = ChangeTags::tagUsageStatistics(); - $definedTags = array_merge( $softwareDefinedTags, $explicitlyDefinedTags ); + $tagHitcounts = array_merge( $softwareDefinedTags, $explicitlyDefinedTags, $tagStats ); + $tags = array_keys( $tagHitcounts ); # Fetch defined tags that aren't past the continuation if ( $params['continue'] !== null ) { $cont = $params['continue']; - $tags = array_filter( array_keys( $definedTags ), function ( $v ) use ( $cont ) { + $tags = array_filter( $tags, function ( $v ) use ( $cont ) { return $v >= $cont; } ); - $tags = array_fill_keys( $tags, 0 ); - } else { - $tags = $definedTags; - } - - # Merge in all used tags - $this->addTables( 'change_tag' ); - $this->addFields( 'ct_tag' ); - $this->addFields( [ 'hitcount' => $fld_hitcount ? 'COUNT(*)' : '0' ] ); - $this->addOption( 'LIMIT', $limit + 1 ); - $this->addOption( 'GROUP BY', 'ct_tag' ); - $this->addWhereRange( 'ct_tag', 'newer', $params['continue'], null ); - $res = $this->select( __METHOD__ ); - foreach ( $res as $row ) { - $tags[$row->ct_tag] = (int)$row->hitcount; } # Now make sure the array is sorted for proper continuation - ksort( $tags ); + sort( $tags ); $count = 0; - foreach ( $tags as $tagName => $hitcount ) { + foreach ( $tags as $tagName ) { if ( ++$count > $limit ) { $this->setContinueEnumParameter( 'continue', $tagName ); break; @@ -102,7 +89,7 @@ class ApiQueryTags extends ApiQueryBase { } if ( $fld_hitcount ) { - $tag['hitcount'] = $hitcount; + $tag['hitcount'] = intval( $tagHitcounts[$tagName] ); } $isSoftware = isset( $softwareDefinedTags[$tagName] );