repo/includes/Store/Sql/DispatchStats.php
<?php
declare( strict_types = 1 );
namespace Wikibase\Repo\Store\Sql;
use Wikibase\Lib\Rdbms\RepoDomainDb;
use Wikimedia\Rdbms\IReadableDatabase;
/**
* Utility class for collecting dispatch statistics.
*
* @license GPL-2.0-or-later
*/
class DispatchStats {
private RepoDomainDb $db;
public function __construct( RepoDomainDb $repoDomainDb ) {
$this->db = $repoDomainDb;
}
public function getDispatchStats(): array {
$db = $this->db->connections()->getReadConnection();
$limit = 5000;
$limitedNumberOfChanges = $this->loadLimitedNumberOfChanges( $db, $limit );
if ( $limitedNumberOfChanges === 0 ) {
return [ 'numberOfChanges' => 0 ];
}
$changeTimesStats = $this->loadChangeTimes( $db );
if ( $limitedNumberOfChanges > $limit ) {
$estimate = $this->getWbChangesRowEstimate( $db );
if ( $estimate < $limit ) {
// estimate is outdated
return $this->buildMinimumNumberOfChangesStats( $limitedNumberOfChanges, $changeTimesStats );
}
return $this->buildEstimateStats( $estimate, $changeTimesStats );
}
$numberOfEntities = $this->loadNumberOfEntities( $db );
return $this->buildExactNumberOfChangesStats( $limitedNumberOfChanges, $numberOfEntities, $changeTimesStats );
}
private function loadLimitedNumberOfChanges( IReadableDatabase $db, $limit ): int {
return $db->newSelectQueryBuilder()
->select( '*' )
->from( 'wb_changes' )
->limit( $limit + 1 )
->caller( __METHOD__ )
->fetchRowCount();
}
private function getWbChangesRowEstimate( IReadableDatabase $db ): int {
return $db->newSelectQueryBuilder()
->select( '*' )
->from( 'wb_changes' )
->caller( __METHOD__ )
->estimateRowCount();
}
private function loadNumberOfEntities( IReadableDatabase $db ): int {
return (int)$db->newSelectQueryBuilder()
->select( 'COUNT( DISTINCT change_object_id )' )
->from( 'wb_changes' )
->caller( __METHOD__ )
->fetchField();
}
private function loadChangeTimes( IReadableDatabase $db ): array {
$statsRow = $db->newSelectQueryBuilder()
->select( [
'stalestTime' => 'MIN( change_time )',
'freshestTime' => 'MAX( change_time )',
] )
->from( 'wb_changes' )
->caller( __METHOD__ )
->fetchRow();
return get_object_vars( $statsRow );
}
private function buildMinimumNumberOfChangesStats( int $limitedNumberOfChanges, array $changeTimesStats ): array {
return [
'minimumNumberOfChanges' => $limitedNumberOfChanges,
] + $changeTimesStats;
}
private function buildEstimateStats( int $estimate, array $changeTimesStats ): array {
return [
'estimatedNumberOfChanges' => $estimate,
] + $changeTimesStats;
}
private function buildExactNumberOfChangesStats( int $numberOfChanges, int $numberOfEntities, array $changeTimesStats ): array {
return [
'numberOfChanges' => $numberOfChanges,
'numberOfEntities' => $numberOfEntities,
] + $changeTimesStats;
}
}