1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 2a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 3a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch# found in the LICENSE file. 4a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 5a3f7b4e666c476898878fa745f637129375cd889Ben Murdochclass Bounds(object): 6a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch """Represents a min-max bounds.""" 7a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def __init__(self): 8a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.is_empty_ = True 9a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.min_ = None 10a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.max_ = None 11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @staticmethod 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def CreateFromEvent(event): 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds = Bounds() 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds.AddEvent(event) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return bounds 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __repr__(self): 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.is_empty_: 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "Bounds()" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "Bounds(min=%s,max=%s)" % (self.min_, self.max_) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 24a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @property 25a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def is_empty(self): 26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return self.is_empty_ 27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @property 29a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def min(self): 30a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if self.is_empty_: 31a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return None 32a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return self.min_ 33a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 34a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @property 35a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def max(self): 36a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if self.is_empty_: 37a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return None 38a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return self.max_ 39a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 40a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @property 41a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def bounds(self): 42a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if self.is_empty_: 43a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return None 44a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return self.max_ - self.min_ 45a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 46a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @property 47a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def center(self): 48a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return (self.min_ + self.max_) * 0.5 49a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def Contains(self, other): 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.is_empty or other.is_empty: 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return False 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.min <= other.min and self.max >= other.max 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def ContainsInterval(self, start, end): 56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return self.min <= start and self.max >= end 57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def Intersects(self, other): 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.is_empty or other.is_empty: 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return False 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return not (other.max < self.min or other.min > self.max) 62a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 63a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def Reset(self): 64a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.is_empty_ = True 65a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.min_ = None 66a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.max_ = None 67a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 68a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def AddBounds(self, bounds): 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if bounds.is_empty: 70a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return 71a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.AddValue(bounds.min_) 72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.AddValue(bounds.max_) 73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def AddValue(self, value): 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if self.is_empty_: 76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.max_ = value 77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.min_ = value 78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.is_empty_ = False 79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return 80a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 81a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.max_ = max(self.max_, value) 82a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.min_ = min(self.min_, value) 83a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def AddEvent(self, event): 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.AddValue(event.start) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.AddValue(event.start + event.duration) 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 88a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @staticmethod 89a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def CompareByMinTimes(a, b): 90a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if not a.is_empty and not b.is_empty: 91a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return a.min_ - b.min_ 92a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 93a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if a.is_empty and not b.is_empty: 94a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return -1 95a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 96a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if not a.is_empty and b.is_empty: 97a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return 1 98a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 99a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return 0 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @staticmethod 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def GetOverlapBetweenBounds(first_bounds, second_bounds): 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Compute the overlap duration between first_bounds and second_bounds.""" 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Bounds.GetOverlap(first_bounds.min_, first_bounds.max_, 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) second_bounds.min_, second_bounds.max_) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @staticmethod 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def GetOverlap(first_bounds_min, first_bounds_max, 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) second_bounds_min, second_bounds_max): 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert first_bounds_min <= first_bounds_max 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert second_bounds_min <= second_bounds_max 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) overlapped_range_start = max(first_bounds_min, second_bounds_min) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) overlapped_range_end = min(first_bounds_max, second_bounds_max) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return max(overlapped_range_end - overlapped_range_start, 0) 115