1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5class Bounds(object): 6 """Represents a min-max bounds.""" 7 def __init__(self): 8 self.is_empty_ = True 9 self.min_ = None 10 self.max_ = None 11 12 @staticmethod 13 def CreateFromEvent(event): 14 bounds = Bounds() 15 bounds.AddEvent(event) 16 return bounds 17 18 def __repr__(self): 19 if self.is_empty_: 20 return "Bounds()" 21 else: 22 return "Bounds(min=%s,max=%s)" % (self.min_, self.max_) 23 24 @property 25 def is_empty(self): 26 return self.is_empty_ 27 28 @property 29 def min(self): 30 if self.is_empty_: 31 return None 32 return self.min_ 33 34 @property 35 def max(self): 36 if self.is_empty_: 37 return None 38 return self.max_ 39 40 @property 41 def bounds(self): 42 if self.is_empty_: 43 return None 44 return self.max_ - self.min_ 45 46 @property 47 def center(self): 48 return (self.min_ + self.max_) * 0.5 49 50 def Contains(self, other): 51 if self.is_empty or other.is_empty: 52 return False 53 return self.min <= other.min and self.max >= other.max 54 55 def ContainsInterval(self, start, end): 56 return self.min <= start and self.max >= end 57 58 def Intersects(self, other): 59 if self.is_empty or other.is_empty: 60 return False 61 return not (other.max < self.min or other.min > self.max) 62 63 def Reset(self): 64 self.is_empty_ = True 65 self.min_ = None 66 self.max_ = None 67 68 def AddBounds(self, bounds): 69 if bounds.is_empty: 70 return 71 self.AddValue(bounds.min_) 72 self.AddValue(bounds.max_) 73 74 def AddValue(self, value): 75 if self.is_empty_: 76 self.max_ = value 77 self.min_ = value 78 self.is_empty_ = False 79 return 80 81 self.max_ = max(self.max_, value) 82 self.min_ = min(self.min_, value) 83 84 def AddEvent(self, event): 85 self.AddValue(event.start) 86 self.AddValue(event.start + event.duration) 87 88 @staticmethod 89 def CompareByMinTimes(a, b): 90 if not a.is_empty and not b.is_empty: 91 return a.min_ - b.min_ 92 93 if a.is_empty and not b.is_empty: 94 return -1 95 96 if not a.is_empty and b.is_empty: 97 return 1 98 99 return 0 100 101 @staticmethod 102 def GetOverlapBetweenBounds(first_bounds, second_bounds): 103 """Compute the overlap duration between first_bounds and second_bounds.""" 104 return Bounds.GetOverlap(first_bounds.min_, first_bounds.max_, 105 second_bounds.min_, second_bounds.max_) 106 107 @staticmethod 108 def GetOverlap(first_bounds_min, first_bounds_max, 109 second_bounds_min, second_bounds_max): 110 assert first_bounds_min <= first_bounds_max 111 assert second_bounds_min <= second_bounds_max 112 overlapped_range_start = max(first_bounds_min, second_bounds_min) 113 overlapped_range_end = min(first_bounds_max, second_bounds_max) 114 return max(overlapped_range_end - overlapped_range_start, 0) 115