Refactor spawn stat computation.
This should be a no-op change that will allow us more easily to expose the
different runners to the build metrics in the BEP.
PiperOrigin-RevId: 344808222
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
index b7eaaf1..daad07a 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.runtime;
import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
@@ -169,9 +170,10 @@
}
}
- String spawnSummary = spawnStats.getSummary();
+ ImmutableMap<String, Integer> spawnSummary = spawnStats.getSummary();
+ String spawnSummaryString = SpawnStats.convertSummaryToString(spawnSummary);
if (statsSummary) {
- reporter.handle(Event.info(spawnSummary));
+ reporter.handle(Event.info(spawnSummaryString));
reporter.handle(
Event.info(
String.format(
@@ -191,11 +193,13 @@
executionTime / 1000.0)));
} else {
reporter.handle(Event.info(Joiner.on(", ").join(items)));
- reporter.handle(Event.info(spawnSummary));
+ reporter.handle(Event.info(spawnSummaryString));
}
- event.getResult().getBuildToolLogCollection()
- .addDirectValue("process stats", spawnSummary.getBytes(StandardCharsets.UTF_8));
+ event
+ .getResult()
+ .getBuildToolLogCollection()
+ .addDirectValue("process stats", spawnSummaryString.getBytes(StandardCharsets.UTF_8));
} finally {
if (criticalPathComputer != null) {
eventBus.unregister(criticalPathComputer);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/SpawnStats.java b/src/main/java/com/google/devtools/build/lib/runtime/SpawnStats.java
index 45360a7..1d241bf 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/SpawnStats.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/SpawnStats.java
@@ -16,12 +16,14 @@
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multiset;
import com.google.devtools.build.lib.actions.ActionResult;
import com.google.devtools.build.lib.actions.SpawnResult;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.concurrent.ThreadSafe;
@@ -57,29 +59,30 @@
/*
* Returns a human-readable summary of spawns counted.
*/
- public String getSummary() {
+ public ImmutableMap<String, Integer> getSummary() {
return getSummary(REPORT_FIRST);
}
/*
* Returns a human-readable summary of spawns counted.
*/
- public String getSummary(ImmutableList<String> reportFirst) {
- ResultString result = new ResultString();
+ public ImmutableMap<String, Integer> getSummary(ImmutableList<String> reportFirst) {
+ ImmutableMap.Builder<String, Integer> result = ImmutableMap.builder();
int numActionsWithoutInternal = runners.size();
int numActionsTotal = totalNumberOfActions.get();
+ result.put("total", numActionsTotal);
// First report cache results.
for (String s : reportFirst) {
int count = runners.setCount(s, 0);
if (count > 0) {
- result.add(s, count);
+ result.put(s, count);
}
}
// Account for internal actions such as SymlinkTree.
if (numActionsWithoutInternal < numActionsTotal) {
- result.add("internal", numActionsTotal - numActionsWithoutInternal);
+ result.put("internal", numActionsTotal - numActionsWithoutInternal);
}
// Sort the rest alphabetically
@@ -87,33 +90,34 @@
Collections.sort(list, Comparator.comparing(e -> e.getElement()));
for (Multiset.Entry<String> e : list) {
- result.add(e.getElement(), e.getCount());
+ result.put(e.getElement(), e.getCount());
}
- return numActionsTotal + " process" + (numActionsTotal == 1 ? "" : "es") + result + ".";
+ return result.build();
}
- private static class ResultString {
- StringBuilder result = new StringBuilder();
- int runnersNum = 0;
-
- public void add(String name, int count) {
- runnersNum += 1;
-
- if (result.length() > 0) {
- result.append(", ");
- }
- result.append(count);
- result.append(" ");
- result.append(name);
+ public static String convertSummaryToString(ImmutableMap<String, Integer> spawnSummary) {
+ Integer total = spawnSummary.get("total");
+ if (total == 0) {
+ return "0 processes.";
}
- @Override
- public String toString() {
- if (runnersNum == 0) {
- return "";
- }
- return ": " + result;
+ StringBuilder stringSummary = new StringBuilder();
+ stringSummary.append(total).append(" process");
+ if (total > 1) {
+ stringSummary.append("es");
}
+ String separator = ": ";
+
+ for (Map.Entry<String, Integer> runnerStats : spawnSummary.entrySet()) {
+ if ("total".equals(runnerStats.getKey())) {
+ continue;
+ }
+ stringSummary.append(separator);
+ separator = ", ";
+ stringSummary.append(runnerStats.getValue()).append(' ').append(runnerStats.getKey());
+ }
+ stringSummary.append('.');
+ return stringSummary.toString();
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/SpawnStatsTest.java b/src/test/java/com/google/devtools/build/lib/runtime/SpawnStatsTest.java
index 51d1b3e..b9fe083 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/SpawnStatsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/SpawnStatsTest.java
@@ -37,21 +37,23 @@
@Test
public void emptySet() {
- assertThat(stats.getSummary()).isEqualTo("0 processes.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary())).isEqualTo("0 processes.");
}
@Test
public void one() {
stats.countRunnerName("foo");
stats.incrementActionCount();
- assertThat(stats.getSummary()).isEqualTo("1 process: 1 foo.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("1 process: 1 foo.");
}
@Test
public void oneRemote() {
stats.countRunnerName("remote cache hit");
stats.incrementActionCount();
- assertThat(stats.getSummary()).isEqualTo("1 process: 1 remote cache hit.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("1 process: 1 remote cache hit.");
}
@Test
@@ -60,7 +62,8 @@
stats.countRunnerName("foo");
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("2 processes: 2 foo.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("2 processes: 2 foo.");
}
@Test
@@ -74,7 +77,8 @@
for (int i = 0; i < 6; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("6 processes: 1 a, 2 b, 3 c.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("6 processes: 1 a, 2 b, 3 c.");
}
@Test
@@ -88,7 +92,8 @@
for (int i = 0; i < 6; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("6 processes: 3 a, 2 b, 1 c.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("6 processes: 3 a, 2 b, 1 c.");
}
@Test
@@ -103,7 +108,8 @@
for (int i = 0; i < 7; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("7 processes: 1 remote cache hit, 3 a, 2 b, 1 c.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("7 processes: 1 remote cache hit, 3 a, 2 b, 1 c.");
}
private final SpawnResult rA =
@@ -119,7 +125,8 @@
stats.countActionResult(ActionResult.create(spawns));
stats.incrementActionCount();
- assertThat(stats.getSummary()).isEqualTo("1 process: 1 abc.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("1 process: 1 abc.");
}
@Test
@@ -135,7 +142,8 @@
for (int i = 0; i < 3; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("3 processes: 3 abc.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("3 processes: 3 abc.");
}
@Test
@@ -151,7 +159,8 @@
for (int i = 0; i < 3; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("3 processes: 2 abc, 1 cde.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("3 processes: 2 abc, 1 cde.");
}
@Test
@@ -178,13 +187,15 @@
for (int i = 0; i < 12; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary()).isEqualTo("12 processes: 9 abc, 3 cde.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("12 processes: 9 abc, 3 cde.");
}
@Test
public void onlyInternal() {
stats.incrementActionCount();
- assertThat(stats.getSummary()).isEqualTo("1 process: 1 internal.");
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
+ .isEqualTo("1 process: 1 internal.");
}
@Test
@@ -201,7 +212,7 @@
for (int i = 0; i < 11; i++) {
stats.incrementActionCount();
}
- assertThat(stats.getSummary())
+ assertThat(SpawnStats.convertSummaryToString(stats.getSummary()))
.isEqualTo("11 processes: 1 remote cache hit, 2 internal, 3 a, 2 b, 1 c, 2 z.");
}
}