From 9fd3d4afb1587a47e81d03f476f7b8306c49b945 Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Sat, 16 Dec 2023 00:44:13 -0600 Subject: [PATCH] capture result map from records automatically --- .../container/NBBufferedContainer.java | 56 ++++++++++++++++--- .../scenarios/simframe/optimo/NB_optimo.java | 6 +- .../simframe/optimo/OptimoSearchSettings.java | 3 + 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/lifecycle/scenario/container/NBBufferedContainer.java b/engine-core/src/main/java/io/nosqlbench/engine/core/lifecycle/scenario/container/NBBufferedContainer.java index 87dded650..7ed905d88 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/lifecycle/scenario/container/NBBufferedContainer.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/lifecycle/scenario/container/NBBufferedContainer.java @@ -33,6 +33,9 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.Reader; 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.regex.Matcher; import java.util.regex.Pattern; @@ -170,20 +173,56 @@ public class NBBufferedContainer extends NBBaseComponent implements NBContainer 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) { - if (object instanceof InvokableResult ir) { + Map results = new LinkedHashMap<>(); + if (object instanceof Record record) { + HashSet 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 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) -> { 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) { map.forEach((k, v) -> { 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) { 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) { ArrayList values = new ArrayList<>(); @@ -191,18 +230,21 @@ public class NBBufferedContainer extends NBBaseComponent implements NBContainer values.add(o.toString()); } 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()) { Object[] ary = (Object[]) object; 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) { - getContainerVars().put(stepname, object.toString()); + results.put(stepname, object.toString()); } else { logger.debug("no object was provided to set the container result"); } + logger.info("VARS:"+results); + + getContainerVars().putAll(results); } @Override diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/NB_optimo.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/NB_optimo.java index e04891c32..3ecca4ebd 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/NB_optimo.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/NB_optimo.java @@ -80,13 +80,15 @@ public class NB_optimo extends NBBaseCommand { SimFrameJournal journal = new SimFrameJournal<>(); 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))) ); model.add("threads", 10, 50, 2000, threads -> flywheel.onEvent(ParamChange.of(new SetThreads((int) (threads)))) ); - OptimoSearchSettings optimoSearchParams = new OptimoSearchSettings(params, model); + SimFrameCapture capture = this.perfValueMeasures(flywheel, optimoSearchParams); SimFrameFunction frameFunction = new OptimoFrameFunction(controller, optimoSearchParams, flywheel, capture, journal); diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/OptimoSearchSettings.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/OptimoSearchSettings.java index 787df48f1..eef8d0ca1 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/OptimoSearchSettings.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/OptimoSearchSettings.java @@ -17,8 +17,10 @@ package io.nosqlbench.scenarios.simframe.optimo; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; +import io.nosqlbench.nb.api.engine.util.Unit; public record OptimoSearchSettings( + double startRate, long sample_time_ms, double cutoff_quantile, double cutoff_ms, @@ -26,6 +28,7 @@ public record OptimoSearchSettings( ) { public OptimoSearchSettings(NBCommandParams params, OptimoParamModel model) { this( + params.maybeGet("startrate").flatMap(Unit::doubleCountFor).orElse(1000.0d), params.maybeGet("sample_time_ms").map(Long::parseLong).orElse(5000L), params.maybeGet("cutoff_quantile").map(Double::parseDouble).orElse(0.99), params.maybeGet("cutoff_ms").map(Double::parseDouble).orElse(50.0d),