// Copyright 2008 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.android.stardroid.util; import com.google.android.stardroid.base.Nullable; import com.google.android.stardroid.base.VisibleForTesting; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * Class representing a single, immutable node in the {@link TimingTree}. Each * node contains the name and elapsed time of the watch at the corresponding * node of the {@link StopWatchTree}, as well as references to its children. * * @author Brent Bryan */ public class TimingTreeNode { public final int level; public final String name; public final long elapsedTimeMs; public final List<TimingTreeNode> children; @VisibleForTesting public TimingTreeNode(int level, String name, long elapsedTimeMs, TimingTreeNode... children) { this(level, name, elapsedTimeMs, Arrays.asList(children)); } @VisibleForTesting TimingTreeNode(int level, String name, long elapsedTimeMs, @Nullable List<TimingTreeNode> children) { this.level = level; this.name = name; this.elapsedTimeMs = elapsedTimeMs; this.children = (children == null) ? new ArrayList<TimingTreeNode>() : children; Collections.sort(children, new Comparator<TimingTreeNode>() { @Override public int compare(TimingTreeNode obj1, TimingTreeNode obj2) { return obj1.name.compareTo(obj2.name); } }); } @Override public String toString() { StringBuilder sb = new StringBuilder(); toStringBuilder(sb, elapsedTimeMs, elapsedTimeMs); return sb.toString(); } /** * Writes a String representation of this {@link TimingTreeNode} to the given * {@link StringBuilder}. */ private void toStringBuilder(StringBuilder sb, long parentElapsedTimeMs, long totalElapsedTimeMs) { for (int i = 0; i < level; i++) { sb.append(" "); } sb.append(String.format("%s: %s (Parent: %5.2f%%, Total: %5.2f%%)\n", name, StopWatchImpl .formatTime(elapsedTimeMs), 100.0 * elapsedTimeMs / parentElapsedTimeMs, 100.0 * elapsedTimeMs / totalElapsedTimeMs)); for (TimingTreeNode child : children) { child.toStringBuilder(sb, elapsedTimeMs, totalElapsedTimeMs); } } @Override public boolean equals(Object obj) { if (obj != null && obj instanceof TimingTreeNode) { TimingTreeNode that = (TimingTreeNode) obj; return this.level == that.level && this.name.equals(that.name) && this.elapsedTimeMs == that.elapsedTimeMs && this.children.equals(that.children); } return false; } @Override public int hashCode() { return Arrays.hashCode(new Object[] {level, name, elapsedTimeMs, children}); } }