/**
  * @phutil-external-symbol class PhabricatorStartup
  */
 public function generateData()
 {
     $should_analyze = self::isQueryAnalyzerRequested();
     $log = PhutilServiceProfiler::getInstance()->getServiceCallLog();
     foreach ($log as $key => $entry) {
         $config = idx($entry, 'config', array());
         unset($log[$key]['config']);
         if (!$should_analyze) {
             $log[$key]['explain'] = array('sev' => 7, 'size' => null, 'reason' => pht('Disabled'));
             // Query analysis is disabled for this request, so don't do any of it.
             continue;
         }
         if ($entry['type'] != 'query') {
             continue;
         }
         // For each SELECT query, go issue an EXPLAIN on it so we can flag stuff
         // causing table scans, etc.
         if (preg_match('/^\\s*SELECT\\b/i', $entry['query'])) {
             $conn = PhabricatorEnv::newObjectFromConfig('mysql.implementation', array($entry['config']));
             try {
                 $explain = queryfx_all($conn, 'EXPLAIN %Q', $entry['query']);
                 $badness = 0;
                 $size = 1;
                 $reason = null;
                 foreach ($explain as $table) {
                     $size *= (int) $table['rows'];
                     switch ($table['type']) {
                         case 'index':
                             $cur_badness = 1;
                             $cur_reason = 'Index';
                             break;
                         case 'const':
                             $cur_badness = 1;
                             $cur_reason = 'Const';
                             break;
                         case 'eq_ref':
                             $cur_badness = 2;
                             $cur_reason = 'EqRef';
                             break;
                         case 'range':
                             $cur_badness = 3;
                             $cur_reason = 'Range';
                             break;
                         case 'ref':
                             $cur_badness = 3;
                             $cur_reason = 'Ref';
                             break;
                         case 'fulltext':
                             $cur_badness = 3;
                             $cur_reason = 'Fulltext';
                             break;
                         case 'ALL':
                             if (preg_match('/Using where/', $table['Extra'])) {
                                 if ($table['rows'] < 256 && !empty($table['possible_keys'])) {
                                     $cur_badness = 2;
                                     $cur_reason = pht('Small Table Scan');
                                 } else {
                                     $cur_badness = 6;
                                     $cur_reason = pht('TABLE SCAN!');
                                 }
                             } else {
                                 $cur_badness = 3;
                                 $cur_reason = pht('Whole Table');
                             }
                             break;
                         default:
                             if (preg_match('/No tables used/i', $table['Extra'])) {
                                 $cur_badness = 1;
                                 $cur_reason = pht('No Tables');
                             } else {
                                 if (preg_match('/Impossible/i', $table['Extra'])) {
                                     $cur_badness = 1;
                                     $cur_reason = pht('Empty');
                                 } else {
                                     $cur_badness = 4;
                                     $cur_reason = pht("Can't Analyze");
                                 }
                             }
                             break;
                     }
                     if ($cur_badness > $badness) {
                         $badness = $cur_badness;
                         $reason = $cur_reason;
                     }
                 }
                 $log[$key]['explain'] = array('sev' => $badness, 'size' => $size, 'reason' => $reason);
             } catch (Exception $ex) {
                 $log[$key]['explain'] = array('sev' => 5, 'size' => null, 'reason' => $ex->getMessage());
             }
         }
     }
     return array('start' => PhabricatorStartup::getStartTime(), 'end' => microtime(true), 'log' => $log, 'analyzeURI' => (string) $this->getRequestURI()->alter('__analyze__', true), 'didAnalyze' => $should_analyze);
 }