/** * Returns the set of tasks that are startable. A startable task is currently in STATE_NEW and has * also met all of its starting dependencies. This requires that each starting dependency must be * in STATE_ENDED. In addition if there are any starting or ending dependencies of an task that * are not present in the map, then hat task will never be considered startable. * * @param tasks Map of tasks indexed by their unique identification * @return The set of startable tasks */ private <T extends Task> Set<T> getStartables(Map<Integer, T> tasks) { Set<T> startables = new HashSet<T>(); for (T task : tasks.values()) { // Ignore tasks that have not been started or have not been added // to the schduler. if (task.getState() != Task.STATE_NEW || !startDepends.containsKey(task.getTaskId())) { continue; } // Check if the task has met all of its start dependencies boolean canStart = true; for (int id : startDepends.get(task.getTaskId())) { if (!tasks.containsKey(id) || tasks.get(id).getState() != Task.STATE_ENDED) { canStart = false; break; } } // In addition check that we *know* about all of this task's // ending dependencies. We do not want to accidentally start an // task that we can never end. if (canStart && tasks.keySet().containsAll(endDepends.get(task.getTaskId()))) { startables.add(task); } } return startables; }
/** * Returns the set of tasks that are endable. An endable task is not only in STATE_ENDABLE, but * also has met all of its ending dependencies. To meet this requirement, each ending dependency * must be in either STATE_ENDABLE, STATE_ENDING, or STATE_ENDED. * * @param tasks Map of tasks indexed by their unique identification * @return The set of endable tasks */ private <T extends Task> Set<T> getEndables(Map<Integer, T> tasks) { Set<T> endables = new HashSet<T>(); for (T task : tasks.values()) { // Ignore tasks that are not endable or have not been added to // the scheduler. if (task.getState() != Task.STATE_ENDABLE || !endDepends.containsKey(task.getTaskId())) { continue; } // Check if the task has met all of its end dependencies boolean canEnd = true; for (int id : endDepends.get(task.getTaskId())) { if (!tasks.containsKey(id) || tasks.get(id).getState() < Task.STATE_ENDABLE) { canEnd = false; break; } } if (canEnd) { endables.add(task); } } return endables; }