private function getJobsInRenderOrder()

in web_ui/src/applications/bistro/controllers/BistroJobListViewController.php [337:427]


  private function getJobsInRenderOrder($jobs) {
    list(
      $most_running_first,
      $enabled_first,
      $main_sort) = $this->parseSortOrder(
      $this->prefs->get(BistroJobListPrefs::PREF_SORT_BY));

    // This flips the kind of sort we do, and how most_running & enabled work.
    $sort_ascending = true;
    if (in_array($main_sort, array(
      BistroJobListPrefs::SORT_NAME_DESCENDING,
      BistroJobListPrefs::SORT_RECENTLY_MODIFIED_FIRST,
      BistroJobListPrefs::SORT_RECENTLY_CREATED_FIRST))) {
      $sort_ascending = false;
    } else if (!in_array($main_sort, array(
      BistroJobListPrefs::SORT_NAME_ASCENDING,
      BistroJobListPrefs::SORT_RECENTLY_MODIFIED_LAST,
      BistroJobListPrefs::SORT_RECENTLY_CREATED_LAST))) {
      bistro_monitor_log()->error('Bad main_sort: '.$main_sort);
    }

    // Sorting a key map is way faster than uasort.
    $key_jobid_map = array();
    foreach ($jobs as $job_id => $job) {
      // The game plan is to append fixed-width string fields to the sort
      // key, causing lexical sort to do the right thing.
      $sort_key = '';

      // Option: First sort by the number of running tasks
      if ($most_running_first ===
          BistroJobListPrefs::SORT_RUNNING_TASKS_FIRST) {
        $num_running_shards = count($job->currentRuntimes);
        // Jobs with the most running shards go first
        if ($sort_ascending) {
          $sort_val = 2000000000 - $num_running_shards;  // ok on 32-bit PHP
          if ($sort_val < 0) {  // Should never happen
            bistro_monitor_log()->warn('Job '.$job_id.' has a bad sort key.');
          }
        } else {
          $sort_val = $num_running_shards;
        }
        // Adds 11 bytes: 10 digits, plus '1' if negative or '0' otherwise
        $sort_key .= sprintf('%011d', $sort_val);
      } else if ($most_running_first !== null) {
        bistro_monitor_log()->error(
          'Bad most_running_first: '.$most_running_first);
      }

      // Option: Enabled jobs with nothing running come before disabled ones
      if ($enabled_first ===
          BistroJobListPrefs::SORT_ENABLED_FIRST) {
        if ($sort_ascending) {
          $sort_key .= intval(!$job->enabled->getConsensus());
        } else {
          $sort_key .= intval(!!$job->enabled->getConsensus());
        }
      } else if ($enabled_first !== null) {
        bistro_monitor_log()->error('Bad enabled_first: '.$enabled_first);
      }

      // Only add to the key if sorting by timestamps; job name is always added
      if (in_array($main_sort, array(
        BistroJobListPrefs::SORT_RECENTLY_MODIFIED_FIRST,
        BistroJobListPrefs::SORT_RECENTLY_MODIFIED_LAST))) {
        $sort_key .= sprintf('%011d', $job->modifiedTime->getConsensus());
      } else if (in_array($main_sort, array(
        BistroJobListPrefs::SORT_RECENTLY_CREATED_FIRST,
        BistroJobListPrefs::SORT_RECENTLY_CREATED_LAST))) {
        $sort_key .= sprintf('%011d', $job->createdTime->getConsensus());
      } else if (!in_array($main_sort, array(
        BistroJobListPrefs::SORT_NAME_ASCENDING,
        BistroJobListPrefs::SORT_NAME_DESCENDING))) {
        bistro_monitor_log()->error('Bad main_sort: '.$main_sort);
      }

      $key_jobid_map[$job_id] = $sort_key.$job_id;
    }

    if ($sort_ascending) {
      asort($key_jobid_map);
    } else {
      arsort($key_jobid_map);
    }

    $ordered_jobs = array();
    foreach ($key_jobid_map as $job_id => $job_key) {
      $ordered_jobs[$job_id] = $jobs[$job_id];
    }

    return $ordered_jobs;
  }