Exemplo n.º 1
0
def test_discardi():
    # Empty tree
    e = IntervalTree()
    e.discardi(-1000, -999, "Doesn't exist")
    e.verify()
    assert len(e) == 0

    # Non-existent member should do nothing quietly
    t = trees['ivs1']()
    oldlen = len(t)
    t.discardi(-1000, -999, "Doesn't exist")
    t.verify()
    assert len(t) == oldlen

    # Should discard existing member
    assert Interval(1, 2, '[1,2)') in t
    t.discardi(1, 2, '[1,2)')
    assert len(t) == oldlen - 1
    assert Interval(1, 2, '[1,2)') not in t
Exemplo n.º 2
0
class TaskSet(object):
    """
    Holds a set of tasks in a priority queue.
  """
    def __init__(self):
        self._tasksQueue = TaskUnitPriorityQueue()  # keep r1 < r2 < r3 order.
        self._intervalTree = IntervalTree()

    @property
    def tasks(self):
        return self._tasksQueue.items()

    def add(self, task):
        if not self._tasksQueue.contains(task.taskID):
            self._addTaskToTree(task)
            self._tasksQueue.push(task)
        else:
            raise DuplicateTaskException

    def _addTaskToTree(self, task):
        """
      Adds task to interval tree.
    """
        self._intervalTree.addi(begin=task.release,
                                end=task.deadline,
                                data=task.taskID)

    def remove(self, task):
        self._intervalTree.discardi(task.release, task.deadline, task.taskID)
        self._tasksQueue.remove(task.taskID)

    def _findLatestInterval(self, intervals):
        """
      Find the latest interval.
    """
        latest = intervals[0]
        for interval in intervals:
            if interval.begin > latest.begin:
                latest = interval
        return latest

    def _orIntervals(self, intervalListA, intervalListB):
        return list(set(intervalListA) | set(intervalListB))

    def _conflictPath(self, interval, intervalTree):
        """
      @param interval The interval to find conflicts with.
      @param intervalTree The intervalTree that contains all intervals
      Finds the longest number of intervals that are all overlapping (conflicting).
        For example:
          if A and B conflict and B and C conflict and A is the
          interval we're looking for conflicts with, the returned
          intervals will be A, B, C.
        Another example:
          if D and E conflict and F and G conflict, and we're looking
          for all conflicts with D, only D and E will be returned as
          F and G are not overlapping with either D and E.
    """
        intervals = list(intervalTree.search(interval))
        # if only one interval, check if its the one we're
        # trying to find conflicts with.
        if len(intervals) == 1 and intervals[0] == interval:
            return []
        # now find the latest of all the intervals and get all conflicts
        # with and keep going until there are no more conflicts.
        latestInterval = self._findLatestInterval(intervals)
        # remove all the conflicts, we dont need to check them again.
        intervalTree.remove_overlap(interval)
        # put the latest conflict back into the tree and find its conflicts
        intervalTree.add(latestInterval)
        # now go find all conflicts with the latest interval until there are none.
        return self._orIntervals(
            intervals, self._conflictPath(latestInterval, intervalTree))

    def _intervalConflictAlreadyDetected(self, interval, conflicts):
        """
      Checks to see if interval was already detected to conflict.
    """
        for conflict in conflicts:
            for ival in conflict:
                if ival == interval:
                    return True
        return False

    def findConflicts(self):
        """
      Finds all conflicts within the task set.
    """
        begin = self._intervalTree.begin()
        end = self._intervalTree.end()
        conflicts = []
        conflictObjs = []
        nonConflictsObjs = []
        intervals = sorted(self._intervalTree[begin:end])
        for interval in intervals:
            # check if this interval was already detected to conflict
            if self._intervalConflictAlreadyDetected(interval, conflicts):
                continue
            conflictIntervals = self._conflictPath(interval,
                                                   self._intervalTree.copy())
            if len(conflictIntervals) > 0:  # there was a  conflict
                conflicts.append(conflictIntervals)
                conflictObjs.append(Conflict(conflictIntervals))
            else:
                nonConflictsObjs.append(Conflict(interval))
        return ConflictSet(conflictObjs), ConflictSet(nonConflictsObjs)

    def __iter__(self):
        return self._tasksQueue