def test_empty_init(): tree = IntervalTree() tree.verify() assert not tree assert len(tree) == 0 assert list(tree) == [] assert tree.is_empty()
def test_empty_queries(): t = IntervalTree() e = set() assert len(t) == 0 assert t.is_empty() assert t[3] == e assert t[4:6] == e assert t.begin() == 0 assert t.end() == 0 assert t[t.begin():t.end()] == e assert t.items() == e assert set(t) == e assert set(t.copy()) == e assert t.find_nested() == {} t.verify()
def test_empty_queries(): t = IntervalTree() e = set() assert len(t) == 0 assert t.is_empty() assert t[3] == e assert t[4:6] == e assert t.begin() == 0 assert t.end() == 0 assert t[t.begin():t.end()] == e assert t.items() == e assert set(t) == e assert set(t.copy()) == e assert t.find_nested() == {} assert t.range().is_null() assert t.range().length() == 0 t.verify()
def test_empty_queries(): t = IntervalTree() e = set() assert len(t) == 0 assert t.is_empty() assert t[3] == e assert t[4:6] == e assert t.begin() == 0 assert t.end() == 0 assert t[t.begin():t.end()] == e assert t.overlap(t.begin(), t.end()) == e assert t.envelop(t.begin(), t.end()) == e assert t.items() == e assert set(t) == e assert set(t.copy()) == e assert t.find_nested() == {} assert t.range().is_null() assert t.range().length() == 0 t.verify()
def test_all(): from intervaltree import Interval, IntervalTree from pprint import pprint from operator import attrgetter def makeinterval(lst): return Interval( lst[0], lst[1], "{}-{}".format(*lst) ) ivs = list(map(makeinterval, [ [1,2], [4,7], [5,9], [6,10], [8,10], [8,15], [10,12], [12,14], [14,15], ])) t = IntervalTree(ivs) t.verify() def data(s): return set(map(attrgetter('data'), s)) # Query tests print('Query tests...') assert data(t[4]) == set(['4-7']) assert data(t[4:5]) == set(['4-7']) assert data(t[4:6]) == set(['4-7', '5-9']) assert data(t[9]) == set(['6-10', '8-10', '8-15']) assert data(t[15]) == set() assert data(t.search(5)) == set(['4-7', '5-9']) assert data(t.search(6, 11, strict = True)) == set(['6-10', '8-10']) print(' passed') # Membership tests print('Membership tests...') assert ivs[1] in t assert Interval(1,3, '1-3') not in t assert t.overlaps(4) assert t.overlaps(9) assert not t.overlaps(15) assert t.overlaps(0,4) assert t.overlaps(1,2) assert t.overlaps(1,3) assert t.overlaps(8,15) assert not t.overlaps(15, 16) assert not t.overlaps(-1, 0) assert not t.overlaps(2,4) print(' passed') # Insertion tests print('Insertion tests...') t.add( makeinterval([1,2]) ) # adding duplicate should do nothing assert data(t[1]) == set(['1-2']) t[1:2] = '1-2' # adding duplicate should do nothing assert data(t[1]) == set(['1-2']) t.add(makeinterval([2,4])) assert data(t[2]) == set(['2-4']) t.verify() t[13:15] = '13-15' assert data(t[14]) == set(['8-15', '13-15', '14-15']) t.verify() print(' passed') # Duplication tests print('Interval duplication tests...') t.add(Interval(14,15,'14-15####')) assert data(t[14]) == set(['8-15', '13-15', '14-15', '14-15####']) t.verify() print(' passed') # Copying and casting print('Tree copying and casting...') tcopy = IntervalTree(t) tcopy.verify() assert t == tcopy tlist = list(t) for iv in tlist: assert iv in t for iv in t: assert iv in tlist tset = set(t) assert tset == t.items() print(' passed') # Deletion tests print('Deletion tests...') try: t.remove( Interval(1,3, "Doesn't exist") ) except ValueError: pass else: raise AssertionError("Expected ValueError") try: t.remove( Interval(500, 1000, "Doesn't exist") ) except ValueError: pass else: raise AssertionError("Expected ValueError") orig = t.print_structure(True) t.discard( Interval(1,3, "Doesn't exist") ) t.discard( Interval(500, 1000, "Doesn't exist") ) assert data(t[14]) == set(['8-15', '13-15', '14-15', '14-15####']) t.remove( Interval(14,15,'14-15####') ) assert data(t[14]) == set(['8-15', '13-15', '14-15']) t.verify() assert data(t[2]) == set(['2-4']) t.discard( makeinterval([2,4]) ) assert data(t[2]) == set() t.verify() assert t[14] t.remove_overlap(14) t.verify() assert not t[14] # Emptying the tree #t.print_structure() for iv in sorted(iter(t)): #print('### Removing '+str(iv)+'... ###') t.remove(iv) #t.print_structure() t.verify() #print('') assert len(t) == 0 assert t.is_empty() assert not t t = IntervalTree(ivs) #t.print_structure() t.remove_overlap(1) #t.print_structure() t.verify() t.remove_overlap(8) #t.print_structure() print(' passed') t = IntervalTree(ivs) pprint(t) t.split_overlaps() pprint(t) #import cPickle as pickle #p = pickle.dumps(t) #print(p)
class StorageResource(Resource): def __init__(self, scheduler: Scheduler, name: str, id: int, resources_list: Resources = None, capacity_bytes: int = 0): super().__init__(scheduler, name, id, resources_list, resource_sharing=True) self.capacity = capacity_bytes self._job_allocations: Dict[JobId, Interval] = { } # job_id -> [(start, end, num_bytes)] self._interval_tree = IntervalTree() def currently_allocated_space(self) -> int: intervals = self._interval_tree[self._scheduler.time] allocated_space = sum(interval.data for interval in intervals) assert allocated_space <= self.capacity return allocated_space def available_space(self, start: float, end: float) -> int: """ Available space in the storage resource in a time range (start, end). Should be the same as self._interval_tree.envelop(start, end). """ intervals = self._interval_tree[start:end] interval_starts = [(interval.begin, interval.data) for interval in intervals] interval_ends = [(interval.end, -interval.data) for interval in intervals] interval_points = sorted(interval_starts + interval_ends) # (time, value) # Compute max of prefix sum max_allocated_space = 0 curr_allocated_space = 0 for _, value in interval_points: curr_allocated_space += value max_allocated_space = max(max_allocated_space, curr_allocated_space) assert max_allocated_space <= self.capacity return self.capacity - max_allocated_space def allocate(self, start: float, end: float, num_bytes: int, job: Job): assert self._scheduler.time <= start <= end assert 0 < num_bytes <= self.available_space(start, end) # There should be only one interval per job. assert job.id not in self._job_allocations interval = Interval(start, end, num_bytes) self._job_allocations[job.id] = interval self._interval_tree.add(interval) assert bool(not self._job_allocations) == bool( self._interval_tree.is_empty()) assert len(self._job_allocations) == len( self._interval_tree.all_intervals) if __debug__: self._interval_tree.verify() def free(self, job: Job): interval = self._job_allocations[job.id] self._interval_tree.remove(interval) del self._job_allocations[job.id] assert bool(not self._job_allocations) == bool( self._interval_tree.is_empty()) assert len(self._job_allocations) == len( self._interval_tree.all_intervals) if __debug__: self._interval_tree.verify() def find_first_time_to_fit_job(self, job, time=None, future_reservation=False): raise NotImplementedError def get_allocation_end_times(self): return set(interval.end for interval in self._job_allocations.values())