diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java b/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java new file mode 100644 index 0000000000..c9848ca8b2 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java @@ -0,0 +1,100 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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.devtools.build.lib.profiler.statistics; + +import com.google.devtools.build.lib.profiler.ProfileInfo; +import com.google.devtools.build.lib.profiler.ProfilePhase; + +import java.util.EnumMap; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Extracts and keeps summary statistics from all {@link ProfilePhase}s for formatting to various + * outputs. + */ +public final class PhaseSummaryStatistics implements Iterable<ProfilePhase> { + + private final long totalDurationNanos; + private final EnumMap<ProfilePhase, Long> durations; + + public PhaseSummaryStatistics(ProfileInfo info) { + durations = new EnumMap<>(ProfilePhase.class); + long totalDuration = 0; + for (ProfilePhase phase : ProfilePhase.values()) { + ProfileInfo.Task phaseTask = info.getPhaseTask(phase); + if (phaseTask != null) { + long phaseDuration = info.getPhaseDuration(phaseTask); + totalDuration += phaseDuration; + durations.put(phase, phaseDuration); + } + } + totalDurationNanos = totalDuration; + } + + /** + * @return whether the given {@link ProfilePhase} was executed + */ + public boolean contains(ProfilePhase phase) { + return durations.containsKey(phase); + } + + /** + * @return the execution duration of a given {@link ProfilePhase} + * @throws NoSuchElementException if the given {@link ProfilePhase} was not executed + */ + public long getDurationNanos(ProfilePhase phase) { + checkContains(phase); + return durations.get(phase); + } + + /** + * @return The duration of the phase relative to the sum of all phase durations + * @throws NoSuchElementException if the given {@link ProfilePhase} was not executed + */ + public double getRelativeDuration(ProfilePhase phase) { + checkContains(phase); + return (double) getDurationNanos(phase) / totalDurationNanos; + } + + /** + * Converts {@link #getRelativeDuration(ProfilePhase)} to a percentage string + * @return formatted percentage string ("%.2f%%") or "N/A" when totalNanos is 0. + * @throws NoSuchElementException if the given {@link ProfilePhase} was not executed + */ + public String getPrettyPercentage(ProfilePhase phase) { + checkContains(phase); + if (totalDurationNanos == 0) { + // Return "not available" string if total is 0 and result is undefined. + return "N/A"; + } + return String.format("%.2f%%", getRelativeDuration(phase) * 100); + } + + public long getTotalDuration() { + return totalDurationNanos; + } + + @Override + public Iterator<ProfilePhase> iterator() { + return durations.keySet().iterator(); + } + + private void checkContains(ProfilePhase phase) { + if (!contains(phase)) { + throw new NoSuchElementException("Phase " + phase + " was not executed"); + } + } +} + |