1// Copyright (c) 2010 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/**
6 * LogGroupEntry is a wrapper around log entries, which makes it easier to
7 * find the corresponding start/end of events.
8 *
9 * This is used internally by the log and timeline views to pretty print
10 * collections of log entries.
11 *
12 * @fileoverview
13 */
14
15// TODO(eroman): document these methods!
16
17function LogGroupEntry(origEntry, index) {
18  this.orig = origEntry;
19  this.index = index;
20}
21
22LogGroupEntry.prototype.isBegin = function() {
23  return this.orig.phase == LogEventPhase.PHASE_BEGIN;
24};
25
26LogGroupEntry.prototype.isEnd = function() {
27  return this.orig.phase == LogEventPhase.PHASE_END
28};
29
30LogGroupEntry.prototype.getDepth = function() {
31  var depth = 0;
32  var p = this.parentEntry;
33  while (p) {
34    depth += 1;
35    p = p.parentEntry;
36  }
37  return depth;
38};
39
40function findParentIndex(parentStack, eventType) {
41  for (var i = parentStack.length - 1; i >= 0; --i) {
42    if (parentStack[i].orig.type == eventType)
43      return i;
44  }
45  return -1;
46}
47
48/**
49 * Returns a list of LogGroupEntrys. This basically wraps the original log
50 * entry, but makes it easier to find the start/end of the event.
51 */
52LogGroupEntry.createArrayFrom = function(origEntries) {
53  var groupedEntries = [];
54
55  // Stack of enclosing PHASE_BEGIN elements.
56  var parentStack = [];
57
58  for (var i = 0; i < origEntries.length; ++i) {
59    var origEntry = origEntries[i];
60
61    var groupEntry = new LogGroupEntry(origEntry, i);
62    groupedEntries.push(groupEntry);
63
64    // If this is the end of an event, match it to the start.
65    if (groupEntry.isEnd()) {
66      // Walk up the parent stack to find the corresponding BEGIN for this END.
67      var parentIndex =
68          findParentIndex(parentStack, groupEntry.orig.type);
69
70      if (parentIndex == -1) {
71        // Unmatched end.
72      } else {
73        groupEntry.begin = parentStack[parentIndex];
74
75        // Consider this as the terminator for all open BEGINs up until
76        // parentIndex.
77        while (parentIndex < parentStack.length) {
78          var p = parentStack.pop();
79          p.end = groupEntry;
80        }
81      }
82    }
83
84    // Inherit the current parent.
85    if (parentStack.length > 0)
86      groupEntry.parentEntry = parentStack[parentStack.length - 1];
87
88    if (groupEntry.isBegin())
89      parentStack.push(groupEntry);
90  }
91
92  return groupedEntries;
93}
94