code: private int countSlotsReleased(List<TaskTrackerAction> killTasksList,
        Collection<Task> setupCleanupTasks, TaskTrackerStatus taskTrackerStatus,
        TaskType type) {
      Map<TaskAttemptID, TaskStatus.State> taskState =
        new HashMap<TaskAttemptID, TaskStatus.State>();
  
      if (taskTrackerStatus.getTaskReports() != null) {
        for (TaskStatus ts : taskTrackerStatus.getTaskReports()) {
          taskState.put(ts.getTaskID(), ts.getRunState());
        }
      }
      int released = 0;
      for (TaskTrackerAction action : killTasksList) {
        TaskAttemptID tid = ((KillTaskAction)action).getTaskID();
        if (type == TaskType.MAP && tid.isMap() ||
            type == TaskType.REDUCE && !tid.isMap()) {
          TaskStatus.State state = taskState.get(tid);
          if (TaskStatus.TERMINATING_STATES.contains(state)) {
            // If we are killing a tasks that's already failed, it doesn't count.
            continue;
          }
          released += 1;
        }
      }
      if (setupCleanupTasks != null) {
        released -= setupCleanupTasks.size();
      }
      return released;
    }
docs: Calculate how many MAP/REDUCE (non-setup/cleanup) slots will be released
  right after the heartbeat
  
  @param killTasksList Kill actions the TT received by heartbeat
  @param setupCleanupTasks SetupCleanup tasks TT received by heartbeat
  @param taskTrackerStatus The status of the TT
  @param type The type of the task (MAP/REDUCE)
  @return Number of slots will be released