| Index: tools/telemetry/telemetry/core/timeline/model.py
|
| diff --git a/tools/telemetry/telemetry/core/timeline/model.py b/tools/telemetry/telemetry/core/timeline/model.py
|
| index 1231af16e1dbc2cda830a4aefbae9e7cfc2f9b13..47606a990cf66672179fccb41c00e16683f0fadc 100644
|
| --- a/tools/telemetry/telemetry/core/timeline/model.py
|
| +++ b/tools/telemetry/telemetry/core/timeline/model.py
|
| @@ -7,9 +7,13 @@ trace_viewer project:
|
| https://code.google.com/p/trace-viewer/
|
| '''
|
|
|
| +import telemetry.core.timeline.process as tracing_process
|
| +
|
| # Register importers for data
|
| from telemetry.core.timeline import inspector_importer
|
| -from telemetry.core.timeline.tracing import trace_event_importer
|
| +from telemetry.core.timeline import bounds
|
| +from telemetry.core.timeline import trace_event_importer
|
| +
|
| _IMPORTERS = [
|
| inspector_importer.InspectorTimelineImporter,
|
| trace_event_importer.TraceEventTimelineImporter
|
| @@ -17,38 +21,22 @@ _IMPORTERS = [
|
|
|
| class TimelineModel(object):
|
| def __init__(self, event_data=None, shift_world_to_zero=True):
|
| - self._root_events = []
|
| - self._all_events = []
|
| + self._bounds = bounds.Bounds()
|
| + self._processes = {}
|
| self._frozen = False
|
| self.import_errors = []
|
| self.metadata = []
|
| - self._bounds = None
|
|
|
| if event_data is not None:
|
| self.ImportTraces([event_data], shift_world_to_zero=shift_world_to_zero)
|
|
|
| @property
|
| - def min_timestamp(self):
|
| - if self._bounds is None:
|
| - self.UpdateBounds()
|
| - return self._bounds[0]
|
| + def bounds(self):
|
| + return self._bounds
|
|
|
| @property
|
| - def max_timestamp(self):
|
| - if self._bounds is None:
|
| - self.UpdateBounds()
|
| - return self._bounds[1]
|
| -
|
| - def AddEvent(self, event):
|
| - if self._frozen:
|
| - raise Exception("Cannot add events once recording is done")
|
| - self._root_events.append(event)
|
| -
|
| - def DidFinishRecording(self):
|
| - for event in self._root_events:
|
| - self._all_events.extend(
|
| - event.GetAllChildrenRecursive(include_self=True))
|
| - self._frozen = True
|
| + def processes(self):
|
| + return self._processes
|
|
|
| def ImportTraces(self, traces, shift_world_to_zero=True):
|
| if self._frozen:
|
| @@ -64,44 +52,71 @@ class TimelineModel(object):
|
| # TODO: catch exceptions here and add it to error list
|
| importer.ImportEvents()
|
|
|
| + self.UpdateBounds()
|
| + if not self.bounds.is_empty:
|
| + for process in self._processes.itervalues():
|
| + process.AutoCloseOpenSlices(self.bounds.max)
|
| +
|
| for importer in importers:
|
| importer.FinalizeImport()
|
|
|
| if shift_world_to_zero:
|
| self.ShiftWorldToZero()
|
| + self.UpdateBounds()
|
|
|
| # Because of FinalizeImport, it would probably be a good idea
|
| # to prevent the timeline from from being modified.
|
| - self.DidFinishRecording()
|
| + self._frozen = True
|
|
|
| def ShiftWorldToZero(self):
|
| - if not len(self._root_events):
|
| - return
|
| self.UpdateBounds()
|
| - delta = min(self._root_events, key=lambda e: e.start).start
|
| - for event in self._root_events:
|
| - event.ShiftTimestampsForward(-delta)
|
| -
|
| - def UpdateBounds(self):
|
| - if not len(self._root_events):
|
| - self._bounds = (0, 0)
|
| + if self._bounds.is_empty:
|
| return
|
| + shift_amount = -self._bounds.min
|
| + for event in self.IterAllEvents():
|
| + event.start += shift_amount
|
|
|
| - for e in self._root_events:
|
| - e.UpdateBounds()
|
| -
|
| - first_event = min(self._root_events, key=lambda e: e.start)
|
| - last_event = max(self._root_events, key=lambda e: e.end)
|
| - self._bounds = (first_event.start, last_event.end)
|
| -
|
| - def GetRootEvents(self):
|
| - return self._root_events
|
| + def UpdateBounds(self):
|
| + self._bounds.Reset()
|
| + for event in self.IterAllEvents():
|
| + self._bounds.AddValue(event.start)
|
| + self._bounds.AddValue(event.end)
|
| +
|
| + def GetAllContainers(self):
|
| + containers = []
|
| + def Iter(container):
|
| + containers.append(container)
|
| + for container in container.IterChildContainers():
|
| + Iter(container)
|
| + for process in self._processes.itervalues():
|
| + Iter(process)
|
| + return containers
|
| +
|
| + def IterAllEvents(self):
|
| + for container in self.GetAllContainers():
|
| + for event in container.IterEventsInThisContainer():
|
| + yield event
|
| +
|
| + def GetAllProcesses(self):
|
| + return self._processes.values()
|
| +
|
| + def GetAllThreads(self):
|
| + threads = []
|
| + for process in self._processes.values():
|
| + threads.extend(process.threads.values())
|
| + return threads
|
|
|
| def GetAllEvents(self):
|
| - return self._all_events
|
| + return list(self.IterAllEvents())
|
|
|
| def GetAllEventsOfName(self, name):
|
| - return [e for e in self._all_events if e.name == name]
|
| + return [e for e in self.IterAllEvents() if e.name == name]
|
| +
|
| + def GetOrCreateProcess(self, pid):
|
| + if pid not in self._processes:
|
| + assert not self._frozen
|
| + self._processes[pid] = tracing_process.Process(self, pid)
|
| + return self._processes[pid]
|
|
|
| def _CreateImporter(self, event_data):
|
| for importer_class in _IMPORTERS:
|
|
|