2020import com .google .gson .stream .JsonWriter ;
2121import java .io .IOException ;
2222import java .time .Duration ;
23+ import java .util .Map ;
2324import java .util .concurrent .TimeUnit ;
2425import javax .annotation .Nullable ;
2526
2627/**
27- * Used to inject a whole counter series in one go in the JSON trace profile; these could be used to
28- * represent CPU or memory usages over the course of an invocations (as opposed to individual tasks
29- * such as executing an action).
28+ * Used to inject a whole counter series (or even multiple) in one go in the JSON trace profile;
29+ * these could be used to represent CPU or memory usages over the course of an invocation (as
30+ * opposed to individual tasks such as executing an action).
3031 */
3132final class CounterSeriesTraceData implements TraceData {
32- private final String shortName ;
33- private final String readableName ;
34- private final double [] counterValues ;
33+ private final Map <ProfilerTask , double []> counterSeriesMap ;
3534 private final Duration profileStart ;
3635 private final Duration bucketDuration ;
37- @ Nullable private final String colorName ;
36+ private final int len ;
37+ private String displayName ;
38+ @ Nullable private String colorName ;
3839
40+ /**
41+ * If multiple series are passed: - they will be rendered as stacked chart; - we assume they all
42+ * have the same length; - display name and color are picked from the first profile task in the
43+ * map. However, colors the remaining series are picked arbitrarily by the Trace renderer.
44+ */
3945 CounterSeriesTraceData (
40- ProfilerTask profilerTask ,
41- double [] counterValues ,
46+ Map <ProfilerTask , double []> counterSeriesMap ,
4247 Duration profileStart ,
4348 Duration bucketDuration ) {
44- Preconditions .checkArgument (COUNTER_TASK_TO_SERIES_NAME .containsKey (profilerTask ));
45- this .shortName = profilerTask .description ;
46- this .readableName = COUNTER_TASK_TO_SERIES_NAME .get (profilerTask );
47- this .counterValues = counterValues ;
49+ Integer len = null ;
50+ for (ProfilerTask profilerTask : counterSeriesMap .keySet ()) {
51+ Preconditions .checkState (COUNTER_TASK_TO_SERIES_NAME .containsKey (profilerTask ));
52+ if (len == null ) {
53+ len = counterSeriesMap .get (profilerTask ).length ;
54+
55+ this .displayName = profilerTask .description ;
56+
57+ // Pick acceptable counter colors manually, unfortunately we have to pick from these
58+ // weird reserved names from
59+ // https://github.com/catapult-project/catapult/blob/master/tracing/tracing/base/color_scheme.html
60+ this .colorName = COUNTER_TASK_TO_COLOR .get (profilerTask );
61+ } else {
62+ Preconditions .checkState (len .equals (counterSeriesMap .get (profilerTask ).length ));
63+ }
64+ }
65+ this .len = len ;
66+ this .counterSeriesMap = counterSeriesMap ;
4867 this .profileStart = profileStart ;
4968 this .bucketDuration = bucketDuration ;
5069
51- // Pick acceptable counter colors manually, unfortunately we have to pick from these
52- // weird reserved names from
53- // https://github.com/catapult-project/catapult/blob/master/tracing/tracing/base/color_scheme.html
54- this .colorName = COUNTER_TASK_TO_COLOR .get (profilerTask );
5570 }
5671
5772 // Pick acceptable counter colors manually, unfortunately we have to pick from these
@@ -73,6 +88,7 @@ final class CounterSeriesTraceData implements TraceData {
7388 private static final ImmutableMap <ProfilerTask , String > COUNTER_TASK_TO_SERIES_NAME =
7489 ImmutableMap .ofEntries (
7590 entry (ProfilerTask .ACTION_COUNTS , "action" ),
91+ entry (ProfilerTask .ACTION_CACHE_COUNTS , "local action cache" ),
7692 entry (ProfilerTask .LOCAL_CPU_USAGE , "cpu" ),
7793 entry (ProfilerTask .SYSTEM_CPU_USAGE , "system cpu" ),
7894 entry (ProfilerTask .LOCAL_MEMORY_USAGE , "memory" ),
@@ -86,18 +102,15 @@ final class CounterSeriesTraceData implements TraceData {
86102
87103 @ Override
88104 public void writeTraceData (JsonWriter jsonWriter , long profileStartTimeNanos ) throws IOException {
89- // See https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.msg3086636uq
105+ // See
106+ // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.msg3086636uq
90107 // for how counter series are represented in the Chrome Trace Event format.
91- for (int i = 0 ; i < counterValues . length ; i ++) {
108+ for (int i = 0 ; i < len ; i ++) {
92109 long timeNanos = profileStart .plus (bucketDuration .multipliedBy (i )).toNanos ();
93- // Skip counts equal to zero. They will show up as a thin line in the profile.
94- if (Math .abs (counterValues [i ]) <= 0.00001 ) {
95- continue ;
96- }
97110 jsonWriter .setIndent (" " );
98111 jsonWriter .beginObject ();
99112 jsonWriter .setIndent ("" );
100- jsonWriter .name ("name" ).value (shortName );
113+ jsonWriter .name ("name" ).value (displayName );
101114 jsonWriter .name ("pid" ).value (1 );
102115 if (colorName != null ) {
103116 jsonWriter .name ("cname" ).value (colorName );
@@ -107,7 +120,13 @@ public void writeTraceData(JsonWriter jsonWriter, long profileStartTimeNanos) th
107120 jsonWriter .name ("args" );
108121
109122 jsonWriter .beginObject ();
110- jsonWriter .name (readableName ).value (counterValues [i ]);
123+ for (ProfilerTask profilerTask : counterSeriesMap .keySet ()) {
124+ double value = counterSeriesMap .get (profilerTask )[i ];
125+ // Skip counts equal to zero. They will show up as a thin line in the profile.
126+ if (Math .abs (value ) > 0.00001 ) {
127+ jsonWriter .name (COUNTER_TASK_TO_SERIES_NAME .get (profilerTask )).value (value );
128+ }
129+ }
111130 jsonWriter .endObject ();
112131
113132 jsonWriter .endObject ();
0 commit comments