예제 #1
0
    def __init__(self,
                 trace,
                 content_lens=None,
                 frame_lens=None,
                 activity=None):
        """Create from a LoadingTrace (or json of a trace).

    Args:
      trace: (LoadingTrace/JSON) Loading trace or JSON of a trace.
      content_lens: (ContentClassificationLens) Lens used to annotate the
                    nodes, or None.
      frame_lens: (FrameLoadLens) Lens used to augment graph with load nodes.
      activity:   (ActivityLens) Lens used to augment the edges with the
                   activity.
    """
        if type(trace) == dict:
            trace = loading_trace.LoadingTrace.FromJsonDict(trace)
        self._trace = trace
        self._content_lens = content_lens
        self._frame_lens = frame_lens
        self._activity_lens = activity
        self._BuildDag(trace)
        # Sort before splitting children so that we can correctly dectect if a
        # reparented child is actually a dependency for a child of its new parent.
        try:
            for n in dag.TopologicalSort(self._nodes):
                self._SplitChildrenByTime(self._node_info[n.Index()])
        except AssertionError as exc:
            sys.stderr.write('Bad topological sort: %s\n'
                             'Skipping child split\n' % str(exc))
        self._cache_all = False
        self._node_filter = lambda _: True
예제 #2
0
  def Cost(self, path_list=None):
    """Compute cost of current model.

    Args:
      path_list: if not None, gets a list of NodeInfo in the longest path.

    Returns:
      Cost of the longest path.

    """
    costs = [0] * len(self._nodes)
    for n in dag.TopologicalSort(self._nodes, self._node_filter):
      cost = 0
      if n.Predecessors():
        cost = max([costs[p.Index()] + self._EdgeCost(p, n)
                    for p in n.Predecessors()])
      if not self._cache_all:
        cost += self._NodeCost(n)
      costs[n.Index()] = cost
    max_cost = max(costs)
    assert max_cost > 0  # Otherwise probably the filter went awry.
    if path_list is not None:
      del path_list[:-1]
      n = (i for i in self._nodes if costs[i.Index()] == max_cost).next()
      path_list.append(self._node_info[n.Index()])
      while n.Predecessors():
        n = reduce(lambda costliest, next:
                   next if (self._node_filter(next) and
                            cost[next.Index()] > cost[costliest.Index()])
                        else costliest,
                   n.Predecessors())
        path_list.insert(0, self._node_info[n.Index()])
    return max_cost
예제 #3
0
  def MakeGraphviz(self, output, highlight=None):
    """Output a graphviz representation of our DAG.

    Args:
      output: a file-like output stream which recieves a graphviz dot.
      highlight: a list of node items to emphasize. Any resource url which
        contains any highlight text will be distinguished in the output.
    """
    output.write("""digraph dependencies {
    rankdir = LR;
    """)
    orphans = set()
    try:
      sorted_nodes = dag.TopologicalSort(self._nodes,
                                         node_filter=self._node_filter)
    except AssertionError as exc:
      sys.stderr.write('Bad topological sort: %s\n'
                       'Writing children in order\n' % str(exc))
      sorted_nodes = self._nodes
    for n in sorted_nodes:
      if not n.Successors() and not n.Predecessors():
        orphans.add(n)
    if orphans:
      output.write("""subgraph cluster_orphans {
  color=black;
  label="Orphans";
""")
      for n in orphans:
        output.write(self._GraphvizNode(n.Index(), highlight))
      output.write('}\n')

    output.write("""subgraph cluster_nodes {
  color=invis;
""")
    for n in sorted_nodes:
      if not n.Successors() and not n.Predecessors():
        continue
      output.write(self._GraphvizNode(n.Index(), highlight))

    for n in sorted_nodes:
      for s in n.Successors():
        style = 'color = orange'
        annotations = self._EdgeAnnotation(n, s)
        if 'parser' in annotations:
          style = 'color = red'
        elif 'stack' in annotations:
          style = 'color = blue'
        elif 'script_inferred' in annotations:
          style = 'color = purple'
        if 'timing' in annotations:
          style += '; style=dashed'
        arrow = '[%s; label="%s"]' % (style, self._EdgeCost(n, s))
        output.write('%d -> %d %s;\n' % (n.Index(), s.Index(), arrow))
    output.write('}\n}\n')
예제 #4
0
    def Nodes(self, sort=False):
        """Return iterable of all nodes via their NodeInfos.

    Args:
      sort: if true, return nodes in sorted order. This may prune additional
        nodes from the unsorted list (eg, non-root, non-ad nodes reachable only
        by ad nodes)

    Returns:
      Iterable of node infos.

    """
        if sort:
            return (
                self._node_info[n.Index()]
                for n in dag.TopologicalSort(self._nodes, self._node_filter))
        return (n for n in self._node_info if self._node_filter(n.Node()))
예제 #5
0
  def __init__(self, requests):
    """Create from a parsed request set.

    Args:
      requests: [RequestData, ...] filtered RequestData from loading.log_parser.
    """
    self._BuildDag(requests)
    self._global_start = min([n.StartTime() for n in self._node_info])
    # Sort before splitting children so that we can correctly dectect if a
    # reparented child is actually a dependency for a child of its new parent.
    try:
      for n in dag.TopologicalSort(self._nodes):
        self._SplitChildrenByTime(self._node_info[n.Index()])
    except AssertionError as exc:
      sys.stderr.write('Bad topological sort: %s\n'
                       'Skipping child split\n' % str(exc))
    self._cache_all = False
    self._node_filter = lambda _: True
 def SortedIndicies(self, graph):
     return [n.Index() for n in dag.TopologicalSort(graph._nodes)]
예제 #7
0
 def SortedIndicies(self, graph, node_filter=None):
   return [n.Index() for n in dag.TopologicalSort(graph, node_filter)]