2 # This module implements Gacks handles
8 # GacksHandle is an object representing a handle. A handle is the following
11 # (id, unitstart, unitstop, timestart, timestop)
13 # id is a text identifier for the resource, for example "CPU"
15 # unitstart and unitstop form an interval [unitstart, unitstop) in unit
16 # space. For example, [0, 10) could represent 10% of a CPU.
18 # timestart and timestop form an interval [timestart, timestop) in time
21 # If unitstop==INFINITY, or timestop==INFINITY, then it is treated as infinity
23 # The GacksHandle also doubles as an RSPEC
25 INFINITY = "inf" #sys.maxint
27 def is_lesser_equal(x, y):
36 def is_greater_equal(x, y):
45 def interval_contains(start1, stop1, start2, stop2):
46 return is_lesser_equal(start1, start2) and is_greater_equal(stop1, stop2)
49 def __init__(self, id=None, unitStart=0, unitStop=INFINITY, timeStart=0, timeStop=INFINITY, string=None):
51 self.unitStart = unitStart
52 self.unitStop = unitStop
53 self.timeStart = timeStart
54 self.timeStop = timeStop
56 self.load_from_string(string)
59 return str(self.id) + "#" + \
60 str(self.unitStart) + "-" + str(self.unitStop) + "#" + \
61 str(self.timeStart) + "-" + str(self.timeStop)
63 def parse_range(self, str):
64 parts = str.split("-")
68 if parts[0] != INFINITY:
69 parts[0] = int(parts[0])
71 if parts[1] != INFINITY:
72 parts[1] = int(parts[1])
76 def load_from_string(self, str):
77 parts = str.split("#")
82 (self.unitStart, self.unitStop) = self.parse_range(parts[1])
85 (self.timeStart, self.timeStop) = self.parse_range(parts[2])
87 def get_quantity(self):
88 if self.unitStop == INFINITY:
91 return self.unitStop-self.unitStart
93 def get_duration(self):
94 if self.timeStop == INFINITY:
97 return self.timeStop-self.timeStart
100 print str(self.id) + ": " + \
101 "units " + str(self.unitStart) + "-" + str(self.unitStop) + \
102 "time " + str(self.timeStart) + "-" + str(self.timeStop)
105 return GacksHandle(self.id, self.unitStart, self.unitStop,
106 self.timeStart, self.timeStop)
108 def split_subset(self, suStart, suStop, stStart, stStop):
109 # an arbitrary rectangle can have a subset removed by slicing it into
115 # s = subset (middle) that was sliced out
124 suStart = self.unitStart
126 suStop = self.unitStop
128 stStart = self.timeStart
130 stStop = self.timeStop
132 h1.unitStop = suStart
134 h2.unitStart = suStart
136 h2.timeStop = stStart
138 h3.unitStart = suStart
140 h3.timeStart = stStop
142 h4.unitStart = suStop
144 s.unitStart = suStart
146 s.timeStart = stStart
149 results = [s, h1, h2, h3, h4]
151 for result in results:
152 if result.get_quantity()>0 and result.get_duration()>0:
153 valid_results.append(result)
157 def split_subset_old(self, uStart, uStop, tStart, tStop):
162 results1.extend(i.split_unit(uStart))
167 results1.extend(i.split_unit(uStop))
172 results1.extend(i.split_time(tStart))
177 results1.extend(i.split_time(tStop))
181 def split_unit(self, unit):
182 if is_lesser_equal(unit, self.unitStart) or is_greater_equal(unit, self.unitStop):
192 def split_time(self, time):
193 if is_lesser_equal(time, self.timeStart) or is_greater_equal(time, self.timeStop):
203 def is_superset(self, handle):
204 if self.id != handle.id:
207 if not interval_contains(self.timeStart, self.timeStop, handle.timeStart, handle.timeStop):
210 if not interval_contains(self.unitStart, self.unitStop, self.timeStart, self.timeStop):
215 def is_proper_superset(self, handle):
216 return self.is_superset(handle) and (not self.is_same_cell(handle))
218 def is_same_cell(self, handle):
219 return (self.id == handle.id) and \
220 (self.unitStart == handle.unitStart) and \
221 (self.unitStop == handle.unitStop) and \
222 (self.timeStart == handle.timeStart) and \
223 (self.timeStop == handle.timeStop)
225 def is_same(self, handle):
226 return self.is_same_cell(handle)
228 def is_in_list(self, handle_list):
229 for handle in handle_list:
230 if is_same(self, handle):
234 class GacksRecord(GacksHandle):
235 def __init__(self, id=None, unitStart=0, unitStop=INFINITY, timeStart=0, timeStop=INFINITY, allocatorHRNs=[], consumerHRN=None):
236 GacksHandle.__init__(self, id, unitStart, unitStop, timeStart, timeStop)
237 self.allocatorHRNs = allocatorHRNs
238 self.consumerHRN = consumerHRN
241 GacksHandle.dump(self)
242 print " allocators:", ", ".join(self.allocatorHRNs)
243 print " consumer:", self.consumerHRN
246 return GacksRecord(self.id, self.unitStart, self.unitStop,
247 self.timeStart, self.timeStop,
248 self.allocatorHRNs, self.consumerHRN)
250 def set_allocator(self, callerHRN, allocatorHRN, which, where):
251 # build up a list of the positions of callerHRN inside of the
255 for i, hrn in enumerate(self.allocatorHRNs):
259 pos = positions[which]
261 # truncate the allocator list at the appropriate place.
263 # keep callerHRN in the list and append allocatorHRN after
265 # remove callerHRN and replace with allocatorHRN
268 self.allocatorHRNs = self.allocatorHRNs[:(pos+1)]
270 self.allocatorHRNs = self.allocatorHRNs[:pos]
272 self.allocatorHRNs.append(allocatorHRN)
274 def get_allocators(self):
275 return self.allocatorHRNs
277 def contains_allocator(self, allocatorHRN):
278 return (allocatorHRN in self.allocatorHRNs)
280 def set_consumer(self, consumerHRN):
281 self.consumerHRN = consumerHRN
283 def get_consumer(self):
284 return self.consumerHRN
286 def strings_to_handles(strings):
288 # if given a newline-separated list of strings, then expand it into a list
289 if isinstance(strings, str):
290 expanded_strings = strings.split("\n")
291 elif isinstance(strings, list):
292 expanded_strings = strings
296 # eliminate any blank strings from the list
297 non_blank_strings = []
298 for string in expanded_strings:
300 non_blank_strings.append(string)
303 for line in non_blank_strings:
304 handle = GacksHandle(string = rspec)
305 handles.append(handle)
309 def handles_to_strings(handles):
311 for handle in handles:
312 strings.append(handle.as_string())
315 def rspec_to_handles(rspec):
316 return strings_to_handles(rspec)
318 def find_handle_in_list(list, uStart, uStop, tStart, tStop):
320 if item.unitStart == uStart and \
321 item.unitStop == uStop and \
322 item.timeStart == tStart and \
323 item.timeStop == tStop: