Skip to content

Commit 0805e49

Browse files
committed
Add support for querying ProgressReporter's JSON metric values.
1 parent ce056cb commit 0805e49

File tree

2 files changed

+137
-3
lines changed

2 files changed

+137
-3
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,20 @@ private void checkForExcessiveGarbageCollection() {
867867
lastGCStats = currentGCStats;
868868
}
869869

870+
public Object getJsonMetricValue(JsonMetric metric) {
871+
if (jsonHelper == null) {
872+
return null;
873+
}
874+
return metric.getValue(jsonHelper);
875+
}
876+
877+
public boolean containsJsonMetricValue(JsonMetric metric) {
878+
if (jsonHelper == null) {
879+
return false;
880+
}
881+
return metric.containsValue(jsonHelper);
882+
}
883+
870884
public void recordJsonMetric(JsonMetric metric, Object value) {
871885
if (jsonHelper != null) {
872886
metric.record(jsonHelper, value);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporterJsonHelper.java

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,82 @@ private static List<String> buildKeys(String... keys) {
5454
return Arrays.stream(keys).filter(Objects::nonNull).toList();
5555
}
5656

57+
/**
58+
* Returns the {@link Map} stored in the given object under the given key or null if the map
59+
* does not exist.
60+
*/
61+
@SuppressWarnings("unchecked")
62+
private static Map<String, Object> getMap(Map<String, Object> object, String key) {
63+
Objects.requireNonNull(key, "JSON keys must not be 'null'");
64+
return (Map<String, Object>) object.get(key);
65+
}
66+
67+
/**
68+
* Gets value from {@link #statsHolder} for the given key sequence.
69+
* <p>
70+
* For example for {@code keys = [a, b, c, d]} it will return the value of
71+
* {@code statsHolder[a][b][c][d]}.
72+
*/
73+
private Object getValue(List<String> keys) {
74+
assert !keys.isEmpty();
75+
Map<String, Object> currentLevel = statsHolder;
76+
77+
/*
78+
* Iteratively index into the next level until the second-last key. Return null if there is
79+
* no defined value on some level while traversing.
80+
*/
81+
for (int i = 0; i < keys.size() - 1; i++) {
82+
currentLevel = getMap(currentLevel, keys.get(i));
83+
if (currentLevel == null) {
84+
return null;
85+
}
86+
}
87+
88+
return currentLevel.get(keys.getLast());
89+
}
90+
91+
public Object getAnalysisResults(AnalysisResults key) {
92+
return getValue(buildKeys(ANALYSIS_RESULTS_KEY, key.bucket, key.key));
93+
}
94+
95+
public Object getGeneralInfo(GeneralInfo info) {
96+
return getValue(buildKeys(GENERAL_INFO_KEY, info.bucket, info.key));
97+
}
98+
99+
public Object getImageDetails(ImageDetailKey key) {
100+
return getValue(buildKeys(IMAGE_DETAILS_KEY, key.bucket, key.subBucket, key.jsonKey));
101+
}
102+
103+
public Object getResourceUsage(ResourceUsageKey key) {
104+
return getValue(buildKeys(RESOURCE_USAGE_KEY, key.bucket, key.jsonKey));
105+
}
106+
107+
/**
108+
* Checks if there is a set value from {@link #statsHolder} for the given key sequence.
109+
* <p>
110+
* For example for {@code keys = [a, b, c, d]} it will return true if
111+
* {@code statsHolder[a][b][c][d]} exists.
112+
*/
113+
private boolean containsValue(List<String> keys) {
114+
return getValue(keys) != null;
115+
}
116+
117+
public boolean containsAnalysisResults(AnalysisResults key) {
118+
return containsValue(buildKeys(ANALYSIS_RESULTS_KEY, key.bucket, key.key));
119+
}
120+
121+
public boolean containsGeneralInfo(GeneralInfo info) {
122+
return containsValue(buildKeys(GENERAL_INFO_KEY, info.bucket, info.key));
123+
}
124+
125+
public boolean containsImageDetails(ImageDetailKey key) {
126+
return containsValue(buildKeys(IMAGE_DETAILS_KEY, key.bucket, key.subBucket, key.jsonKey));
127+
}
128+
129+
public boolean containsResourceUsage(ResourceUsageKey key) {
130+
return containsValue(buildKeys(RESOURCE_USAGE_KEY, key.bucket, key.jsonKey));
131+
}
132+
57133
/**
58134
* Returns the {@link Map} stored in the given object under the given key.
59135
* <p>
@@ -108,11 +184,15 @@ public void print(JsonWriter writer) throws IOException {
108184
writer.print(statsHolder);
109185
}
110186

111-
interface JsonMetric {
187+
public interface JsonMetric {
188+
Object getValue(ProgressReporterJsonHelper helper);
189+
190+
boolean containsValue(ProgressReporterJsonHelper helper);
191+
112192
void record(ProgressReporterJsonHelper helper, Object value);
113193
}
114194

115-
enum ImageDetailKey implements JsonMetric {
195+
public enum ImageDetailKey implements JsonMetric {
116196
TOTAL_SIZE(null, null, "total_bytes"),
117197
CODE_AREA_SIZE("code_area", null, "bytes"),
118198
NUM_COMP_UNITS("code_area", null, "compilation_units"),
@@ -134,13 +214,23 @@ enum ImageDetailKey implements JsonMetric {
134214
this.subBucket = subBucket;
135215
}
136216

217+
@Override
218+
public Object getValue(ProgressReporterJsonHelper helper) {
219+
return helper.getImageDetails(this);
220+
}
221+
222+
@Override
223+
public boolean containsValue(ProgressReporterJsonHelper helper) {
224+
return helper.containsImageDetails(this);
225+
}
226+
137227
@Override
138228
public void record(ProgressReporterJsonHelper helper, Object value) {
139229
helper.putImageDetails(this, value);
140230
}
141231
}
142232

143-
enum ResourceUsageKey implements JsonMetric {
233+
public enum ResourceUsageKey implements JsonMetric {
144234
CPU_LOAD("cpu", "load"),
145235
CPU_CORES_TOTAL("cpu", "total_cores"),
146236
GC_COUNT("garbage_collection", "count"),
@@ -159,6 +249,16 @@ enum ResourceUsageKey implements JsonMetric {
159249
this.jsonKey = key;
160250
}
161251

252+
@Override
253+
public Object getValue(ProgressReporterJsonHelper helper) {
254+
return helper.getResourceUsage(this);
255+
}
256+
257+
@Override
258+
public boolean containsValue(ProgressReporterJsonHelper helper) {
259+
return helper.containsResourceUsage(this);
260+
}
261+
162262
@Override
163263
public void record(ProgressReporterJsonHelper helper, Object value) {
164264
helper.putResourceUsage(this, value);
@@ -199,6 +299,16 @@ public String bucket() {
199299
return bucket;
200300
}
201301

302+
@Override
303+
public Object getValue(ProgressReporterJsonHelper helper) {
304+
return helper.getAnalysisResults(this);
305+
}
306+
307+
@Override
308+
public boolean containsValue(ProgressReporterJsonHelper helper) {
309+
return helper.containsAnalysisResults(this);
310+
}
311+
202312
@Override
203313
public void record(ProgressReporterJsonHelper helper, Object value) {
204314
if (value instanceof Integer v) {
@@ -234,6 +344,16 @@ public String jsonKey() {
234344
return key;
235345
}
236346

347+
@Override
348+
public Object getValue(ProgressReporterJsonHelper helper) {
349+
return helper.getGeneralInfo(this);
350+
}
351+
352+
@Override
353+
public boolean containsValue(ProgressReporterJsonHelper helper) {
354+
return helper.containsGeneralInfo(this);
355+
}
356+
237357
@Override
238358
public void record(ProgressReporterJsonHelper helper, Object value) {
239359
if (value instanceof String || value instanceof Boolean || value instanceof List || value == null) {

0 commit comments

Comments
 (0)