capture result map from records automatically

This commit is contained in:
Jonathan Shook
2023-12-16 00:44:13 -06:00
parent c3a42c1a75
commit 9fd3d4afb1
3 changed files with 56 additions and 9 deletions

View File

@@ -33,6 +33,9 @@ import java.io.InputStreamReader;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.Reader; import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -170,20 +173,56 @@ public class NBBufferedContainer extends NBBaseComponent implements NBContainer
return NBCommandParams.of(interpolated); return NBCommandParams.of(interpolated);
} }
/**
* Apply the result of a command execution to the container variables.
*
* @param stepname The step name of the command result.
* @param object The result object of the command execution.
*/
private void applyResult(String stepname, Object object) { private void applyResult(String stepname, Object object) {
if (object instanceof InvokableResult ir) { Map<String,String> results = new LinkedHashMap<>();
if (object instanceof Record record) {
HashSet<String> filtered = new HashSet<>(Set.of("hashCode","toString","getClass","notify","notifyAll","wait"));
RecordComponent[] recordComponents = record.getClass().getRecordComponents();
for (RecordComponent component : recordComponents) {
try {
String name = component.getName();
Object value = component.getAccessor().invoke(record);
results.put(stepname+"."+name,value.toString());
filtered.add(name);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
List<Method> properties = Arrays.stream(record.getClass().getMethods())
.filter(m -> m.getParameterCount() == 0)
.filter(m -> !filtered.contains(m.getName()))
.toList();
for (Method property : properties) {
try {
Object value = property.invoke(record);
results.put(stepname+"."+property.getName(),value.toString());
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
} else if (object instanceof InvokableResult ir) {
ir.asResult().forEach((k, v) -> { ir.asResult().forEach((k, v) -> {
logger.debug("setting InvokableResult command result for '" + stepname + "." + k + "' to '" + v + "'"); logger.debug("setting InvokableResult command result for '" + stepname + "." + k + "' to '" + v + "'");
getContainerVars().put(stepname + "." + k, v); results.put(stepname + "." + k, v);
}); });
} else if (object instanceof Map<?, ?> map) { } else if (object instanceof Map<?, ?> map) {
map.forEach((k, v) -> { map.forEach((k, v) -> {
logger.debug("setting command result for '" + stepname + "." + k + "' to '" + v.toString() + "'"); logger.debug("setting command result for '" + stepname + "." + k + "' to '" + v.toString() + "'");
getContainerVars().put(stepname + "." + k, v.toString()); results.put(stepname + "." + k, v.toString());
}); });
} else if (object instanceof List<?> list) { } else if (object instanceof List<?> list) {
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
getContainerVars().put(stepname + "." + String.valueOf(i), list.get(i).toString()); results.put(stepname + "." + i, list.get(i).toString());
} }
} else if (object instanceof Set<?> set) { } else if (object instanceof Set<?> set) {
ArrayList<String> values = new ArrayList<>(); ArrayList<String> values = new ArrayList<>();
@@ -191,18 +230,21 @@ public class NBBufferedContainer extends NBBaseComponent implements NBContainer
values.add(o.toString()); values.add(o.toString());
} }
for (int i = 0; i < values.size(); i++) { for (int i = 0; i < values.size(); i++) {
getContainerVars().put(stepname + "." + String.valueOf(i), values.get(i)); results.put(stepname + "." + i, values.get(i));
} }
} else if (object != null && object.getClass().isArray()) { } else if (object != null && object.getClass().isArray()) {
Object[] ary = (Object[]) object; Object[] ary = (Object[]) object;
for (int i = 0; i < ary.length; i++) { for (int i = 0; i < ary.length; i++) {
getContainerVars().put(stepname + "." + String.valueOf(i), String.valueOf(ary[i])); results.put(stepname + "." + i, String.valueOf(ary[i]));
} }
} else if (object != null) { } else if (object != null) {
getContainerVars().put(stepname, object.toString()); results.put(stepname, object.toString());
} else { } else {
logger.debug("no object was provided to set the container result"); logger.debug("no object was provided to set the container result");
} }
logger.info("VARS:"+results);
getContainerVars().putAll(results);
} }
@Override @Override

View File

@@ -80,13 +80,15 @@ public class NB_optimo extends NBBaseCommand {
SimFrameJournal<OptimoFrameParams> journal = new SimFrameJournal<>(); SimFrameJournal<OptimoFrameParams> journal = new SimFrameJournal<>();
OptimoParamModel model = new OptimoParamModel(); OptimoParamModel model = new OptimoParamModel();
model.add("rate", 20, 50, 1000000, OptimoSearchSettings optimoSearchParams = new OptimoSearchSettings(params, model);
model.add("rate", 20, optimoSearchParams.startRate(), optimoSearchParams.startRate()*4,
rate -> flywheel.onEvent(ParamChange.of(new CycleRateSpec(rate, 1.1d, SimRateSpec.Verb.restart))) rate -> flywheel.onEvent(ParamChange.of(new CycleRateSpec(rate, 1.1d, SimRateSpec.Verb.restart)))
); );
model.add("threads", 10, 50, 2000, model.add("threads", 10, 50, 2000,
threads -> flywheel.onEvent(ParamChange.of(new SetThreads((int) (threads)))) threads -> flywheel.onEvent(ParamChange.of(new SetThreads((int) (threads))))
); );
OptimoSearchSettings optimoSearchParams = new OptimoSearchSettings(params, model);
SimFrameCapture capture = this.perfValueMeasures(flywheel, optimoSearchParams); SimFrameCapture capture = this.perfValueMeasures(flywheel, optimoSearchParams);
SimFrameFunction frameFunction = new OptimoFrameFunction(controller, optimoSearchParams, flywheel, capture, journal); SimFrameFunction frameFunction = new OptimoFrameFunction(controller, optimoSearchParams, flywheel, capture, journal);

View File

@@ -17,8 +17,10 @@
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimo;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.engine.util.Unit;
public record OptimoSearchSettings( public record OptimoSearchSettings(
double startRate,
long sample_time_ms, long sample_time_ms,
double cutoff_quantile, double cutoff_quantile,
double cutoff_ms, double cutoff_ms,
@@ -26,6 +28,7 @@ public record OptimoSearchSettings(
) { ) {
public OptimoSearchSettings(NBCommandParams params, OptimoParamModel model) { public OptimoSearchSettings(NBCommandParams params, OptimoParamModel model) {
this( this(
params.maybeGet("startrate").flatMap(Unit::doubleCountFor).orElse(1000.0d),
params.maybeGet("sample_time_ms").map(Long::parseLong).orElse(5000L), params.maybeGet("sample_time_ms").map(Long::parseLong).orElse(5000L),
params.maybeGet("cutoff_quantile").map(Double::parseDouble).orElse(0.99), params.maybeGet("cutoff_quantile").map(Double::parseDouble).orElse(0.99),
params.maybeGet("cutoff_ms").map(Double::parseDouble).orElse(50.0d), params.maybeGet("cutoff_ms").map(Double::parseDouble).orElse(50.0d),