@Override
 public int compare(Schedulable s1, Schedulable s2) {
   double minShareRatio1, minShareRatio2;
   double tasksToWeightRatio1, tasksToWeightRatio2;
   int minShare1 = Math.min(s1.getMinShare(), s1.getDemand());
   int minShare2 = Math.min(s2.getMinShare(), s2.getDemand());
   boolean s1Needy = s1.getRunningTasks() < minShare1;
   boolean s2Needy = s2.getRunningTasks() < minShare2;
   minShareRatio1 = s1.getRunningTasks() / Math.max(minShare1, 1.0);
   minShareRatio2 = s2.getRunningTasks() / Math.max(minShare2, 1.0);
   tasksToWeightRatio1 = s1.getRunningTasks() / s1.getWeight();
   tasksToWeightRatio2 = s2.getRunningTasks() / s2.getWeight();
   int res = 0;
   if (s1Needy && !s2Needy) res = -1;
   else if (s2Needy && !s1Needy) res = 1;
   else if (s1Needy && s2Needy) res = (int) Math.signum(minShareRatio1 - minShareRatio2);
   else // Neither schedulable is needy
   res = (int) Math.signum(tasksToWeightRatio1 - tasksToWeightRatio2);
   if (res == 0) {
     // Jobs are tied in fairness ratio. Break the tie by submit time and job
     // name to get a deterministic ordering, which is useful for unit tests.
     res = (int) Math.signum(s1.getStartTime() - s2.getStartTime());
     if (res == 0) res = s1.getName().compareTo(s2.getName());
   }
   return res;
 }
 @Override
 public int compare(Schedulable s1, Schedulable s2) {
   int res = s1.getPriority().compareTo(s2.getPriority());
   if (res == 0) {
     res = (int) Math.signum(s1.getStartTime() - s2.getStartTime());
   }
   if (res == 0) {
     // In the rare case where jobs were submitted at the exact same time,
     // compare them by name (which will be the JobID) to get a deterministic
     // ordering, so we don't alternately launch tasks from different jobs.
     res = s1.getName().compareTo(s2.getName());
   }
   return res;
 }