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 5 6class TimelineBasedMetricException(Exception): 7 """Exception that can be thrown from metrics that implements 8 TimelineBasedMetric to indicate a problem arose when computing the metric. 9 """ 10 11 12def _TimeRangesHasOverlap(iterable_time_ranges): 13 """ Returns True if there is are overlapped ranges in time ranges. 14 iterable_time_ranges: an iterable of time ranges. Each time range is a 15 tuple (start time, end time). 16 """ 17 # Sort the ranges by the start time 18 sorted_time_ranges = sorted(iterable_time_ranges) 19 last_range = sorted_time_ranges[0] 20 for current_range in sorted_time_ranges[1:]: 21 start_current_range = current_range[0] 22 end_last_range = last_range[1] 23 if start_current_range < end_last_range: 24 return True 25 last_range = current_range 26 return False 27 28 29def IsEventInInteractions(event, interaction_records): 30 """ Return True if event is in any of the interaction records' time range. 31 32 Args: 33 event: an instance of telemetry.timeline.event.TimelineEvent. 34 interaction_records: a list of interaction records, whereas each record is 35 an instance of 36 telemetry.web_perf.timeline_interaction_record.TimelineInteractionRecord. 37 38 Returns: 39 True if |event|'s start & end time is in any of the |interaction_records|'s 40 time range. 41 """ 42 return any(ir.start <= event.start and ir.end >= event.end for ir 43 in interaction_records) 44 45 46class TimelineBasedMetric(object): 47 48 def __init__(self): 49 """Computes metrics from a telemetry.timeline Model and a range 50 51 """ 52 super(TimelineBasedMetric, self).__init__() 53 54 def AddResults(self, model, renderer_thread, interaction_records, results): 55 """Computes and adds metrics for the interaction_records' time ranges. 56 57 The override of this method should compute results on the data **only** 58 within the interaction_records' start and end time ranges. 59 60 Args: 61 model: An instance of telemetry.timeline.model.TimelineModel. 62 interaction_records: A list of instances of TimelineInteractionRecord. If 63 the override of this method doesn't support overlapped ranges, use 64 VerifyNonOverlappedRecords to check that no records are overlapped. 65 results: An instance of page.PageTestResults. 66 67 """ 68 raise NotImplementedError() 69 70 def AddWholeTraceResults(self, model, results): 71 """Computes and adds metrics corresponding to the entire trace. 72 73 Override this method to compute results that correspond to the whole trace. 74 75 Args: 76 model: An instance of telemetry.timeline.model.TimelineModel. 77 results: An instance of page.PageTestResults. 78 """ 79 pass 80 81 def VerifyNonOverlappedRecords(self, interaction_records): 82 """This raises exceptions if interaction_records contain overlapped ranges. 83 """ 84 if _TimeRangesHasOverlap(((r.start, r.end) for r in interaction_records)): 85 raise TimelineBasedMetricException( 86 'This metric does not support interaction records with overlapped ' 87 'time range.') 88