specialize op template collection into a more useful type

This commit is contained in:
Jonathan Shook
2024-12-22 19:19:21 -06:00
parent 638095a82a
commit a8bbd9f923
17 changed files with 438 additions and 352 deletions

View File

@@ -20,6 +20,7 @@ package io.nosqlbench.adapter.diag;
import io.nosqlbench.adapters.api.activityconfig.OpsLoader; import io.nosqlbench.adapters.api.activityconfig.OpsLoader;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplateFormat; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplateFormat;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList;
import io.nosqlbench.adapters.api.activityimpl.OpMapper; import io.nosqlbench.adapters.api.activityimpl.OpMapper;
import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter; import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter;
@@ -107,9 +108,12 @@ public class DiagDriverAdapter extends BaseDriverAdapter<DiagOp, DiagSpace> impl
} }
@Override @Override
public List<OpTemplate> getSyntheticOpTemplates(OpsDocList opsDocList, Map<String, Object> params) { public OpTemplates getSyntheticOpTemplates(
return OpsLoader.loadString("noop: noop", OpTemplateFormat.inline, params,null).getOps(true); OpTemplates opTemplates,
// return OpsLoader.loadString("log:level=INFO", OpTemplateFormat.inline, params,null).getOps(); Map<String, Object> params) {
OpTemplates matching = OpsLoader.loadString(
"noop: noop", OpTemplateFormat.inline, params, null).getOps().matching("", true);
return matching;
} }
} }

View File

@@ -54,7 +54,7 @@ public class HttpOpMapperTest {
private static ParsedOp parsedOpFor(final String yaml) { private static ParsedOp parsedOpFor(final String yaml) {
final OpsDocList docs = OpsLoader.loadString(yaml, OpTemplateFormat.yaml, Map.of(), null); final OpsDocList docs = OpsLoader.loadString(yaml, OpTemplateFormat.yaml, Map.of(), null);
final OpTemplate opTemplate = docs.getOps(true).get(0); final OpTemplate opTemplate = docs.getOps().get(0);
final ParsedOp parsedOp = new ParsedOp(opTemplate, HttpOpMapperTest.cfg, List.of(HttpOpMapperTest.adapter.getPreprocessor()), new TestComponent("parent","parent")); final ParsedOp parsedOp = new ParsedOp(opTemplate, HttpOpMapperTest.cfg, List.of(HttpOpMapperTest.adapter.getPreprocessor()), new TestComponent("parent","parent"));
return parsedOp; return parsedOp;
} }

View File

@@ -18,6 +18,7 @@ package io.nosqlbench.adapter.stdout;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpData; import io.nosqlbench.adapters.api.activityconfig.yaml.OpData;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList;
import io.nosqlbench.adapters.api.activityimpl.OpMapper; import io.nosqlbench.adapters.api.activityimpl.OpMapper;
import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter; import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter;
@@ -59,26 +60,27 @@ public class StdoutDriverAdapter extends BaseDriverAdapter<StdoutOp, StdoutSpace
@Override @Override
public NBConfigModel getConfigModel() { public NBConfigModel getConfigModel() {
return ConfigModel.of(this.getClass()) return ConfigModel.of(this.getClass()).add(super.getConfigModel()).add(
.add(super.getConfigModel()) StdoutSpace.getConfigModel());
.add(StdoutSpace.getConfigModel());
} }
@Override @Override
public List<OpTemplate> getSyntheticOpTemplates(OpsDocList opsDocList, Map<String, Object> cfg) { public OpTemplates getSyntheticOpTemplates(OpTemplates opTempl, Map<String, Object> cfg) {
Set<String> activeBindingNames = new LinkedHashSet<>(opsDocList.getDocBindings().keySet()); Set<String> activeBindingNames = new LinkedHashSet<>(opTempl.getDocBindings().keySet());
if (activeBindingNames.isEmpty()) { if (activeBindingNames.isEmpty()) {
logger.warn("Unable to synthesize op for driver=" + this.getAdapterName() + " with zero bindings."); logger.warn(
return List.of(); "Unable to synthesize op for driver=" + this.getAdapterName() + " with zero bindings.");
return new OpTemplates(List.of(),OpsDocList.none());
} }
String bindings = Optional.ofNullable(cfg.get("bindings")).map(Object::toString).orElse("doc"); String bindings = Optional.ofNullable(cfg.get("bindings")).map(Object::toString).orElse(
Pattern bindingsFilter = Pattern.compile(bindings.equalsIgnoreCase("doc") ? ".*" : bindings); "doc");
Pattern bindingsFilter = Pattern.compile(
bindings.equalsIgnoreCase("doc") ? ".*" : bindings);
Set<String> filteredBindingNames = activeBindingNames Set<String> filteredBindingNames = activeBindingNames.stream().filter(n -> {
.stream()
.filter(n -> {
if (bindingsFilter.matcher(n).matches()) { if (bindingsFilter.matcher(n).matches()) {
logger.trace(() -> "bindings filter kept binding '" + n + "'"); logger.trace(() -> "bindings filter kept binding '" + n + "'");
return true; return true;
@@ -86,30 +88,29 @@ public class StdoutDriverAdapter extends BaseDriverAdapter<StdoutOp, StdoutSpace
logger.trace(() -> "bindings filter removed binding '" + n + "'"); logger.trace(() -> "bindings filter removed binding '" + n + "'");
return false; return false;
} }
}) }).collect(Collectors.toSet());
.collect(Collectors.toSet());
if (filteredBindingNames.isEmpty()) { if (filteredBindingNames.isEmpty()) {
logger.warn("Unable to synthesize op for driver="+getAdapterName()+" when " + activeBindingNames.size()+"/"+activeBindingNames.size() + " bindings were filtered out with bindings=" + bindings); logger.warn(
return List.of(); "Unable to synthesize op for driver=" + getAdapterName() + " when " + activeBindingNames.size() + "/" + activeBindingNames.size() + " bindings were filtered out with bindings=" + bindings);
return new OpTemplates(List.of(),OpsDocList.none());
} }
OpData op = new OpData("synthetic", "synthetic", Map.of(), opsDocList.getDocBindings(), cfg, OpData op = new OpData(
Map.of("stmt", genStatementTemplate(filteredBindingNames, cfg)),200); "synthetic", "synthetic", Map.of(), opTempl.getDocBindings(), cfg,
Map.of("stmt", genStatementTemplate(filteredBindingNames, cfg)), 200
);
return List.of(op); return new OpTemplates(List.of(op),OpsDocList.none());
} }
private String genStatementTemplate(Set<String> keySet, Map<String, Object> cfg) { private String genStatementTemplate(Set<String> keySet, Map<String, Object> cfg) {
TemplateFormat format = Optional.ofNullable(cfg.get("format")) TemplateFormat format = Optional.ofNullable(cfg.get("format")).map(Object::toString).map(
.map(Object::toString) TemplateFormat::valueOf).orElse(TemplateFormat.assignments);
.map(TemplateFormat::valueOf)
.orElse(TemplateFormat.assignments);
boolean ensureNewline = Optional.ofNullable(cfg.get("newline")) boolean ensureNewline = Optional.ofNullable(cfg.get("newline")).map(Object::toString).map(
.map(Object::toString) Boolean::valueOf).orElse(true);
.map(Boolean::valueOf)
.orElse(true);
String stmtTemplate = format.format(ensureNewline, new ArrayList<>(keySet)); String stmtTemplate = format.format(ensureNewline, new ArrayList<>(keySet));
return stmtTemplate; return stmtTemplate;

View File

@@ -17,6 +17,7 @@
package io.nosqlbench.adapter.tcpclient; package io.nosqlbench.adapter.tcpclient;
import io.nosqlbench.adapter.stdout.StdoutDriverAdapter; import io.nosqlbench.adapter.stdout.StdoutDriverAdapter;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.nb.api.config.standard.ConfigModel; import io.nosqlbench.nb.api.config.standard.ConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfigModel; import io.nosqlbench.nb.api.config.standard.NBConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfiguration; import io.nosqlbench.nb.api.config.standard.NBConfiguration;
@@ -67,7 +68,9 @@ public class TcpClientDriverAdapter extends BaseDriverAdapter<TcpClientOp, TcpCl
} }
@Override @Override
public List<OpTemplate> getSyntheticOpTemplates(OpsDocList opsDocList, Map<String,Object> cfg) { public OpTemplates getSyntheticOpTemplates(
OpTemplates opsDocList,
Map<String,Object> cfg) {
return adap.getSyntheticOpTemplates(opsDocList, cfg); return adap.getSyntheticOpTemplates(opsDocList, cfg);
} }

View File

@@ -16,6 +16,7 @@
package io.nosqlbench.adapter.tcpserver; package io.nosqlbench.adapter.tcpserver;
import io.nosqlbench.adapter.stdout.StdoutDriverAdapter; import io.nosqlbench.adapter.stdout.StdoutDriverAdapter;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.nb.api.config.standard.ConfigModel; import io.nosqlbench.nb.api.config.standard.ConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfigModel; import io.nosqlbench.nb.api.config.standard.NBConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfiguration; import io.nosqlbench.nb.api.config.standard.NBConfiguration;
@@ -65,7 +66,9 @@ public class TcpServerDriverAdapter extends BaseDriverAdapter<TcpServerOp, TcpSe
} }
@Override @Override
public List<OpTemplate> getSyntheticOpTemplates(OpsDocList opsDocList, Map<String,Object> cfg) { public OpTemplates getSyntheticOpTemplates(
OpTemplates opsDocList,
Map<String,Object> cfg) {
return adap.getSyntheticOpTemplates(opsDocList, cfg); return adap.getSyntheticOpTemplates(opsDocList, cfg);
} }

View File

@@ -16,8 +16,10 @@
package io.nosqlbench.adapters.api.activityconfig.rawyaml; package io.nosqlbench.adapters.api.activityconfig.rawyaml;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -39,6 +41,13 @@ public class RawOpsDocList implements Iterable<RawOpsDoc> {
return new RawOpsDocList(List.of()); return new RawOpsDocList(List.of());
} }
public static RawOpsDocList combine(RawOpsDocList l1, RawOpsDocList l2) {
List<RawOpsDoc> rawOpsDocs = new ArrayList<>();
rawOpsDocs.addAll(l1.getOpsDocs());
rawOpsDocs.addAll(l2.getOpsDocs());
return new RawOpsDocList(rawOpsDocs);
}
public List<RawOpsDoc> getOpsDocs() { public List<RawOpsDoc> getOpsDocs() {
return rawOpsDocList; return rawOpsDocList;
} }

View File

@@ -0,0 +1,92 @@
package io.nosqlbench.adapters.api.activityconfig.yaml;
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsDocList;
import io.nosqlbench.nb.api.tagging.TagFilter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.stream.Stream;
/// [OpTemplates] is a list of selected op templates and their backing data.
///
/// It is a value type which makes it easy to /// get matching subsets of op templates according to tag filters, to combine them, etc.
///
/// When a user selects an op template, they are expected to use the [TagFilter] mechanism.
/// Any such lookup methods should be implemented on this class.
public class OpTemplates implements Iterable<OpTemplate> {
private final ArrayList<OpTemplate> templates = new ArrayList<>();
private final static Logger logger = LogManager.getLogger(OpTemplates.class);
private final OpsDocList opsDocList;
public OpTemplates(OpsDocList opsDocList) {
opsDocList.getStmtDocs().stream().flatMap(d -> d.getOpTemplates().stream()).forEach(templates::add);
this.opsDocList = opsDocList;
}
public OpTemplates(List<OpTemplate> matchingOpTemplates, OpsDocList opsDocList) {
this.opsDocList = opsDocList;
templates.addAll(matchingOpTemplates);
}
public OpTemplates() {
this.opsDocList=new OpsDocList(new RawOpsDocList(List.of()));
}
public OpTemplates and(OpTemplates other) {
this.opsDocList.and(opsDocList);
return new OpTemplates();
}
/**
* @param tagFilterSpec a comma-separated tag filter spec
* @return The list of all included op templates for all included blocks of in this document,
* including the inherited and overridden values from this doc and the parent block.
*/
public OpTemplates matching(String tagFilterSpec, boolean logit) {
TagFilter ts = new TagFilter(tagFilterSpec);
List<OpTemplate> matchingOpTemplates = new ArrayList<>();
List<String> matchlog = new ArrayList<>();
templates.stream()
.map(ts::matchesTaggedResult)
.peek(r -> matchlog.add(r.getLog()))
.filter(TagFilter.Result::matched)
.map(TagFilter.Result::getElement)
.forEach(matchingOpTemplates::add);
if (logit) {
for (String s : matchlog) {
logger.info(s);
}
}
return new OpTemplates(matchingOpTemplates,opsDocList);
}
public Map<String,String> getDocBindings() {
return opsDocList.getDocBindings();
}
@Override
public @NotNull Iterator<OpTemplate> iterator() {
return templates.iterator();
}
public Stream<OpTemplate> stream() {
return templates.stream();
}
public int size() {
return templates.size();
}
public OpTemplate get(int idx) {
return templates.get(idx);
}
public boolean isEmpty() {
return this.templates.isEmpty();
}
}

View File

@@ -43,6 +43,11 @@ public class OpsDocList implements Iterable<OpsDoc> {
// this.applyModifier(new enumerator()); // this.applyModifier(new enumerator());
} }
private OpsDocList(RawOpsDocList rawOpsDocList, Map<String, String> templateVariables) {
this.rawOpsDocList = rawOpsDocList;
this.templateVariables.putAll(templateVariables);
}
public static OpsDocList none() { public static OpsDocList none() {
return new OpsDocList(RawOpsDocList.none()); return new OpsDocList(RawOpsDocList.none());
} }
@@ -60,41 +65,10 @@ public class OpsDocList implements Iterable<OpsDoc> {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public List<OpTemplate> getOps(boolean logit) { public OpTemplates getOps() {
return getOps("", logit); return new OpTemplates(this);
} }
/**
* @param tagFilterSpec a comma-separated tag filter spec
* @return The list of all included op templates for all included blocks of in this document,
* including the inherited and overridden values from this doc and the parent block.
*/
public List<OpTemplate> getOps(String tagFilterSpec, boolean logit) {
TagFilter ts = new TagFilter(tagFilterSpec);
List<OpTemplate> opTemplates = new ArrayList<>();
List<OpTemplate> rawtemplates = getStmtDocs().stream()
.flatMap(d -> d.getOpTemplates().stream()).toList();
List<String> matchlog = new ArrayList<>();
rawtemplates.stream()
.map(ts::matchesTaggedResult)
.peek(r -> matchlog.add(r.getLog()))
.filter(TagFilter.Result::matched)
.map(TagFilter.Result::getElement)
.forEach(opTemplates::add);
if (logit) {
for (String s : matchlog) {
logger.info(s);
}
}
return opTemplates;
}
@Override @Override
public Iterator<OpsDoc> iterator() { public Iterator<OpsDoc> iterator() {
return getStmtDocs().iterator(); return getStmtDocs().iterator();
@@ -196,4 +170,13 @@ public class OpsDocList implements Iterable<OpsDoc> {
return count; return count;
} }
public OpsDocList and(OpsDocList other) {
return new OpsDocList(
RawOpsDocList.combine(this.rawOpsDocList,other.rawOpsDocList),
new LinkedHashMap<>() {{
putAll(templateVariables);
putAll(other.templateVariables);
}}
);
}
} }

View File

@@ -17,6 +17,7 @@
package io.nosqlbench.adapters.api.activityimpl.uniform.decorators; package io.nosqlbench.adapters.api.activityimpl.uniform.decorators;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList;
import io.nosqlbench.adapters.api.templating.DriverAdapterDecorators; import io.nosqlbench.adapters.api.templating.DriverAdapterDecorators;
@@ -41,10 +42,10 @@ public interface SyntheticOpTemplateProvider extends DriverAdapterDecorators {
* If a driver adapter supports creating example op templates from bindings, * If a driver adapter supports creating example op templates from bindings,
* it must implement this method to do so. * it must implement this method to do so.
* *
* @param opsDocList * @param opTemplates
* The existing doc structure, which should contain no fully defined op templates, but may contain other * The existing doc structure, which should contain no fully defined op templates, but may contain other
* elements like bindings * elements like bindings
* @return A list of op templates, size zero or more * @return A list of op templates, size zero or more
*/ */
List<OpTemplate> getSyntheticOpTemplates(OpsDocList opsDocList, Map<String, Object> params); OpTemplates getSyntheticOpTemplates(OpTemplates opTemplates, Map<String, Object> params);
} }

View File

@@ -22,6 +22,7 @@ import io.nosqlbench.adapters.api.activityconfig.OpsLoader;
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsLoader; import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsLoader;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplateFormat; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplateFormat;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList;
import io.nosqlbench.nb.spectest.api.STAssemblyValidator; import io.nosqlbench.nb.spectest.api.STAssemblyValidator;
import io.nosqlbench.nb.spectest.core.STNodeAssembly; import io.nosqlbench.nb.spectest.core.STNodeAssembly;
@@ -110,7 +111,7 @@ public class YamlSpecValidator implements STAssemblyValidator {
List<Map<String, Object>> expectedList = gson.fromJson(json, type); List<Map<String, Object>> expectedList = gson.fromJson(json, type);
OpsDocList stmtsDocs = OpsLoader.loadString(yaml, OpTemplateFormat.yaml, new HashMap<>(), null); OpsDocList stmtsDocs = OpsLoader.loadString(yaml, OpTemplateFormat.yaml, new HashMap<>(), null);
List<OpTemplate> stmts = stmtsDocs.getOps(false); OpTemplates stmts = stmtsDocs.getOps();
List<Map<String, Object>> stmt_objs = stmts.stream().map(OpTemplate::asData).collect(Collectors.toList()); List<Map<String, Object>> stmt_objs = stmts.stream().map(OpTemplate::asData).collect(Collectors.toList());
try { try {

View File

@@ -130,9 +130,9 @@ public class OpsDocListTest {
@Test @Test
public void testFilteredStmts() { public void testFilteredStmts() {
List<OpTemplate> stmts = doclist.getOps("",true); OpTemplates stmts = doclist.getOps().matching("", true);
Assertions.assertThat(stmts).hasSize(6); Assertions.assertThat(stmts).hasSize(6);
stmts = doclist.getOps("root1:value23",true); stmts = doclist.getOps().matching("root1:value23",true);
Assertions.assertThat(stmts).hasSize(2); Assertions.assertThat(stmts).hasSize(2);
} }

View File

@@ -81,8 +81,8 @@ public class ParsedOpTest {
ps1: "param-one" ps1: "param-one"
"""; """;
final OpsDocList stmtsDocs = OpsLoader.loadString(opt, OpTemplateFormat.yaml, cfg.getMap(), null); final OpsDocList stmtsDocs = OpsLoader.loadString(opt, OpTemplateFormat.yaml, cfg.getMap(), null);
assertThat(stmtsDocs.getOps(true).size()).isEqualTo(1); assertThat(stmtsDocs.getOps().matching("",true).size()).isEqualTo(1);
final OpTemplate opTemplate = stmtsDocs.getOps(true).get(0); final OpTemplate opTemplate = stmtsDocs.getOps().matching("",true).get(0);
final ParsedOp parsedOp = new ParsedOp(opTemplate, cfg, List.of(), getParent()); final ParsedOp parsedOp = new ParsedOp(opTemplate, cfg, List.of(), getParent());
assertThat(parsedOp.getAsFunctionOr("d1", "invalid").apply(1L)).isEqualTo("one"); assertThat(parsedOp.getAsFunctionOr("d1", "invalid").apply(1L)).isEqualTo("one");

View File

@@ -105,15 +105,6 @@ public class ActivityDef implements NBNamedElement {
return parameterMap.getOptionalString("alias").orElse(DEFAULT_ALIAS); return parameterMap.getOptionalString("alias").orElse(DEFAULT_ALIAS);
} }
/**
* Return tbe StandardActivity Driver Adapter Name
*
* @return the driver adapter name
*/
public String getActivityDriver() {
return parameterMap.getOptionalString("type", "driver").orElse(DEFAULT_ATYPE);
}
/** /**
* The first cycle that will be used for execution of this activity, inclusive. * The first cycle that will be used for execution of this activity, inclusive.
* If the value is provided as a range as in 0..10, then the first number is the start cycle * If the value is provided as a range as in 0..10, then the first number is the start cycle

View File

@@ -35,12 +35,12 @@ public class NBCLIScenarioPreprocessorTemplateVarTest {
cmds.forEach(System.out::println); cmds.forEach(System.out::println);
OpsDocList workload1 = OpsLoader.loadPath(cmds.get(0).getArgValue("workload"), cmds.get(0).getArgMap()); OpsDocList workload1 = OpsLoader.loadPath(cmds.get(0).getArgValue("workload"), cmds.get(0).getArgMap());
OpTemplate optpl1 = workload1.getOps(true).get(0); OpTemplate optpl1 = workload1.getOps().matching("",true).get(0);
System.out.println("op from cmd1:" + optpl1); System.out.println("op from cmd1:" + optpl1);
assertThat(optpl1.getStmt()).contains("cycle {cycle} replaced replaced\n"); assertThat(optpl1.getStmt()).contains("cycle {cycle} replaced replaced\n");
OpsDocList workload2 = OpsLoader.loadPath(cmds.get(1).getArgValue("workload"), cmds.get(1).getArgMap()); OpsDocList workload2 = OpsLoader.loadPath(cmds.get(1).getArgValue("workload"), cmds.get(1).getArgMap());
OpTemplate optpl2 = workload2.getOps(true).get(0); OpTemplate optpl2 = workload2.getOps().matching("",true).get(0);
System.out.println("op from cmd2:" + optpl2); System.out.println("op from cmd2:" + optpl2);
assertThat(optpl2.getStmt()).contains("cycle {cycle} def1 def1\n"); assertThat(optpl2.getStmt()).contains("cycle {cycle} def1 def1\n");
} }
@@ -52,7 +52,7 @@ public class NBCLIScenarioPreprocessorTemplateVarTest {
cmds.forEach(System.out::println); cmds.forEach(System.out::println);
OpsDocList workload1 = OpsLoader.loadPath(cmds.get(0).getArgValue("workload"), cmds.get(0).getArgMap()); OpsDocList workload1 = OpsLoader.loadPath(cmds.get(0).getArgValue("workload"), cmds.get(0).getArgMap());
OpTemplate optpl1 = workload1.getOps(true).get(0); OpTemplate optpl1 = workload1.getOps().matching("",true).get(0);
System.out.println("op from cmd1:" + optpl1); System.out.println("op from cmd1:" + optpl1);
assertThat(optpl1.getStmt()).contains("cycle {cycle} overridden overridden\n"); assertThat(optpl1.getStmt()).contains("cycle {cycle} overridden overridden\n");
} }

View File

@@ -54,14 +54,13 @@ public class ComponentActivityInstrumentation {
public ComponentActivityInstrumentation(final Activity activity) { public ComponentActivityInstrumentation(final Activity activity) {
this.activity = activity; this.activity = activity;
def = activity.getActivityDef(); def = activity.getActivityDef();
this.hdrdigits = activity.getComponentProp("hdr_digits").map(Integer::parseInt).orElse(3);
params = this.def.getParams(); params = this.def.getParams();
hdrdigits = activity.getHdrDigits();
initMetrics(); initMetrics();
} }
private void initMetrics() { private void initMetrics() {
this.errorRate1m = activity.create().gauge("error_rate_1m", this.errorRate1m = activity.create().gauge("error_rate_1m",
() -> { () -> {
double result_1m_rate = this.resultTimer.getOneMinuteRate(); double result_1m_rate = this.resultTimer.getOneMinuteRate();

View File

@@ -16,11 +16,11 @@
package io.nosqlbench.engine.api.activityimpl.uniform; package io.nosqlbench.engine.api.activityimpl.uniform;
import com.codahale.metrics.Timer;
import io.nosqlbench.adapter.diag.DriverAdapterLoader; import io.nosqlbench.adapter.diag.DriverAdapterLoader;
import io.nosqlbench.adapters.api.activityconfig.OpsLoader; import io.nosqlbench.adapters.api.activityconfig.OpsLoader;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplateFormat; import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplateFormat;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList;
import io.nosqlbench.adapters.api.activityimpl.OpDispenser; import io.nosqlbench.adapters.api.activityimpl.OpDispenser;
import io.nosqlbench.adapters.api.activityimpl.OpLookup; import io.nosqlbench.adapters.api.activityimpl.OpLookup;
@@ -58,9 +58,6 @@ import io.nosqlbench.nb.api.advisor.NBAdvisorOutput;
import io.nosqlbench.nb.api.components.status.NBStatusComponent; import io.nosqlbench.nb.api.components.status.NBStatusComponent;
import io.nosqlbench.nb.api.engine.activityimpl.ParameterMap; import io.nosqlbench.nb.api.engine.activityimpl.ParameterMap;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory; import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricCounter;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricHistogram;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricTimer;
import io.nosqlbench.nb.api.lifecycle.Shutdownable; import io.nosqlbench.nb.api.lifecycle.Shutdownable;
import io.nosqlbench.nb.api.components.core.NBComponent; import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.config.standard.*; import io.nosqlbench.nb.api.config.standard.*;
@@ -77,13 +74,8 @@ import io.nosqlbench.nb.api.tagging.TagFilter;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.function.LongFunction; import java.util.function.LongFunction;
/// An [[Activity]] is a flywheel of operations. Each activity consumes ordinals /// An [[Activity]] is a flywheel of operations. Each activity consumes ordinals
@@ -115,10 +107,8 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
private final RunStateTally tally = new RunStateTally(); private final RunStateTally tally = new RunStateTally();
private ThreadLocal<RateLimiter> strideLimiterSource; private ThreadLocal<RateLimiter> strideLimiterSource;
private ThreadLocal<RateLimiter> cycleLimiterSource; private ThreadLocal<RateLimiter> cycleLimiterSource;
private int nameEnumerator;
private NBErrorHandler errorHandler; private NBErrorHandler errorHandler;
private final List<AutoCloseable> closeables = new ArrayList<>(); private final List<AutoCloseable> closeables = new ArrayList<>();
private PrintWriter console;
private ErrorMetrics errorMetrics; private ErrorMetrics errorMetrics;
private Input input; private Input input;
private StandardAction<?, ?> action; private StandardAction<?, ?> action;
@@ -132,36 +122,25 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
this.activityDef = activityDef; this.activityDef = activityDef;
this.metrics = new ActivityMetrics(this); this.metrics = new ActivityMetrics(this);
if (activityDef.getAlias().equals(ActivityDef.DEFAULT_ALIAS)) { getParams().set(
Optional<String> workloadOpt = activityDef.getParams().getOptionalString( "alias", Optional.ofNullable(activityDef.getAlias()).or(
"workload", "yaml"); () -> getParams().getOptionalString("workload")).or(
if (workloadOpt.isPresent()) { () -> getParams().getOptionalString("driver")).orElseThrow(
activityDef.getParams().set("alias", workloadOpt.get()); () -> new RuntimeException(
} else { "Unable to determine name of activity from " + activityDef))
activityDef.getParams().set(
"alias", activityDef.getActivityDriver().toUpperCase(
Locale.ROOT) + nameEnumerator
); );
nameEnumerator++;
}
}
OpsDocList workload; OpsDocList workload;
Optional<String> yaml_loc = activityDef.getParams().getOptionalString("yaml", "workload"); Optional<String> yaml_loc = activityDef.getParams().getOptionalString("yaml", "workload");
NBConfigModel yamlmodel;
if (yaml_loc.isPresent()) { NBConfigModel yamlmodel = yaml_loc.map(path -> {
Map<String, Object> disposable = new LinkedHashMap<>(activityDef.getParams()); return OpsLoader.loadPath(
workload = OpsLoader.loadPath(yaml_loc.get(), disposable, "activities"); path, new LinkedHashMap<>(activityDef.getParams()), "activities").getConfigModel();
yamlmodel = workload.getConfigModel(); }).orElse(ConfigModel.of(Activity.class).asReadOnly());
} else {
yamlmodel = ConfigModel.of(Activity.class).asReadOnly();
}
Optional<String> defaultDriverName = activityDef.getParams().getOptionalString("driver"); Optional<String> defaultDriverName = activityDef.getParams().getOptionalString("driver");
Optional<DriverAdapter<?, ?>> defaultAdapter = activityDef.getParams().getOptionalString(
Optional<DriverAdapter<?, ?>> defaultAdapter = defaultDriverName.flatMap( "driver").flatMap(name -> ServiceSelector.of(
name -> ServiceSelector.of(
name, ServiceLoader.load(DriverAdapterLoader.class)).get()).map( name, ServiceLoader.load(DriverAdapterLoader.class)).get()).map(
l -> l.load(this, NBLabels.forKV())); l -> l.load(this, NBLabels.forKV()));
@@ -170,9 +149,13 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
"Unable to load '" + defaultDriverName.get() + "' driver adapter.\n" + "Rebuild NB5 to include this driver adapter. " + "Change '<activeByDefault>false</activeByDefault>' for the driver in " + "'./nb-adapters/pom.xml' and './nb-adapters/nb-adapters-included/pom.xml' first."); "Unable to load '" + defaultDriverName.get() + "' driver adapter.\n" + "Rebuild NB5 to include this driver adapter. " + "Change '<activeByDefault>false</activeByDefault>' for the driver in " + "'./nb-adapters/pom.xml' and './nb-adapters/nb-adapters-included/pom.xml' first.");
} }
OpResolver opResolver = new OpResolver(() -> loadOpTemplates());
// HERE, op templates are loaded before drivers are loaded // HERE, op templates are loaded before drivers are loaded
// List<OpTemplate> opTemplates = loadOpTemplates(defaultAdapter.orElse(null), false); // List<OpTemplate> opTemplates = loadOpTemplates(defaultAdapter.orElse(null), false);
List<DriverAdapter<CycleOp<?>, Space>> adapterlist = new ArrayList<>(); List<DriverAdapter<CycleOp<?>, Space>> adapterlist = new ArrayList<>();
NBConfigModel supersetConfig = ConfigModel.of(Activity.class).add(yamlmodel); NBConfigModel supersetConfig = ConfigModel.of(Activity.class).add(yamlmodel);
Optional<String> defaultDriverOption = defaultDriverName; Optional<String> defaultDriverOption = defaultDriverName;
ConcurrentHashMap<String, OpMapper<? extends CycleOp<?>, ? extends Space>> mappers = new ConcurrentHashMap<>(); ConcurrentHashMap<String, OpMapper<? extends CycleOp<?>, ? extends Space>> mappers = new ConcurrentHashMap<>();
@@ -207,14 +190,18 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
"Error mapping workload template to operations: " + e.getMessage(), null, e); "Error mapping workload template to operations: " + e.getMessage(), null, e);
} }
initOpsMetrics();
}
private void initOpsMetrics() {
create().gauge( create().gauge(
"ops_pending", () -> this.getProgressMeter().getSummary().pending(), "ops_pending", () -> this.getProgressMeter().getSummary().pending(),
MetricCategory.Core, MetricCategory.Core,
"The current number of operations which have not been dispatched for processing yet." "The current number of operations which have not been dispatched for processing yet."
); );
create().gauge( create().gauge(
"ops_active", () -> this.getProgressMeter().getSummary().current(), "ops_active", () -> this.getProgressMeter().getSummary().current(), MetricCategory.Core,
MetricCategory.Core,
"The current number of operations which have been dispatched for processing, but which have not yet completed." "The current number of operations which have been dispatched for processing, but which have not yet completed."
); );
create().gauge( create().gauge(
@@ -227,18 +214,14 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
protected <O extends LongFunction> OpSequence<OpDispenser<? extends CycleOp<?>>> createOpSourceFromParsedOps( protected <O extends LongFunction> OpSequence<OpDispenser<? extends CycleOp<?>>> createOpSourceFromParsedOps(
List<DriverAdapter<CycleOp<?>, Space>> adapters, List<ParsedOp> pops, List<DriverAdapter<CycleOp<?>, Space>> adapters, List<ParsedOp> pops, OpLookup opLookup) {
OpLookup opLookup
) {
return createOpSourceFromParsedOps2(adapters, pops, opLookup); return createOpSourceFromParsedOps2(adapters, pops, opLookup);
} }
protected <O extends LongFunction> OpSequence<OpDispenser<? extends CycleOp<?>>> createOpSourceFromParsedOps2( protected <O extends LongFunction> OpSequence<OpDispenser<? extends CycleOp<?>>> createOpSourceFromParsedOps2(
// Map<String, DriverAdapter<?,?>> adapterCache, // Map<String, DriverAdapter<?,?>> adapterCache,
// Map<String, OpMapper<? extends Op>> mapperCache, // Map<String, OpMapper<? extends Op>> mapperCache,
List<DriverAdapter<CycleOp<?>, Space>> adapters, List<ParsedOp> pops, List<DriverAdapter<CycleOp<?>, Space>> adapters, List<ParsedOp> pops, OpLookup opLookup) {
OpLookup opLookup
) {
try { try {
List<Long> ratios = new ArrayList<>(pops.size()); List<Long> ratios = new ArrayList<>(pops.size());
@@ -337,8 +320,8 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
DriverAdapter<CycleOp<?>, Space> adapter = Optional.of(driverName).flatMap( DriverAdapter<CycleOp<?>, Space> adapter = Optional.of(driverName).flatMap(
name -> ServiceSelector.of( name -> ServiceSelector.of(
name, ServiceLoader.load(DriverAdapterLoader.class)).get()).map( name, ServiceLoader.load(DriverAdapterLoader.class)).get()).map(
l -> l.load(this, NBLabels.forKV())).orElseThrow(() -> new OpConfigError( l -> l.load(this, NBLabels.forKV())).orElseThrow(
"driver adapter not present for name '" + driverName + "'")); () -> new OpConfigError("driver adapter not present for name '" + driverName + "'"));
NBConfigModel combinedModel = yamlmodel; NBConfigModel combinedModel = yamlmodel;
NBConfiguration combinedConfig = combinedModel.matchConfig(activityDef.getParams()); NBConfiguration combinedConfig = combinedModel.matchConfig(activityDef.getParams());
@@ -390,36 +373,17 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
} }
} }
// @Override
// public synchronized void onActivityDefUpdate(final ActivityDef activityDef) {
// super.onActivityDefUpdate(activityDef);
//
// for (final DriverAdapter adapter : this.adapters.values())
// if (adapter instanceof NBReconfigurable reconfigurable) {
// NBConfigModel cfgModel = reconfigurable.getReconfigModel();
// final Optional<String> op_yaml_loc = activityDef.getParams().getOptionalString("yaml", "workload");
// if (op_yaml_loc.isPresent()) {
// final Map<String, Object> disposable = new LinkedHashMap<>(activityDef.getParams());
// final OpsDocList workload = OpsLoader.loadPath(op_yaml_loc.get(), disposable, "activities");
// cfgModel = cfgModel.add(workload.getConfigModel());
// }
// final NBConfiguration cfg = cfgModel.apply(activityDef.getParams());
// reconfigurable.applyReconfig(cfg);
// }
//
// }
@Override @Override
public List<OpTemplate> getSyntheticOpTemplates( public OpTemplates getSyntheticOpTemplates(OpTemplates opsDocList, Map<String, Object> cfg) {
OpsDocList opsDocList, Map<String, Object> cfg) { OpTemplates accumulator = new OpTemplates();
List<OpTemplate> opTemplates = new ArrayList<>(); List<OpTemplates> combined = new ArrayList<>();
for (DriverAdapter<?, ?> adapter : adapters.values()) { for (DriverAdapter<?, ?> adapter : adapters.values()) {
if (adapter instanceof SyntheticOpTemplateProvider sotp) { if (adapter instanceof SyntheticOpTemplateProvider sotp) {
List<OpTemplate> newTemplates = sotp.getSyntheticOpTemplates(opsDocList, cfg); OpTemplates newTemplates = sotp.getSyntheticOpTemplates(opsDocList, cfg);
opTemplates.addAll(newTemplates); accumulator = accumulator.and(newTemplates);
} }
} }
return opTemplates; return accumulator;
} }
/** /**
@@ -458,29 +422,27 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
} }
} }
protected List<OpTemplate> loadOpTemplates( private OpTemplates loadOpTemplates(
DriverAdapter<?, ?> defaultDriverAdapter, boolean logged, boolean filtered) { DriverAdapter<?, ?> defaultDriverAdapter, boolean logged, boolean filtered) {
String tagfilter = activityDef.getParams().getOptionalString("tags").orElse(""); String tagfilter = activityDef.getParams().getOptionalString("tags").orElse("");
OpsDocList opsDocList = loadStmtsDocList(); OpTemplates templates = loadOpTemplates();
OpTemplates filteredOps = templates.matching(filtered ? tagfilter : "", logged);
List<OpTemplate> filteredOps = opsDocList.getOps(filtered ? tagfilter : "", logged);
if (filteredOps.isEmpty()) { if (filteredOps.isEmpty()) {
// There were no ops, and it *wasn't* because they were all filtered out. // There were no ops, and it *wasn't* because they were all filtered out.
// In this case, let's try to synthesize the ops as long as at least a default driver was provided // In this case, let's try to synthesize the ops as long as at least a default driver was provided
// But if there were no ops, and there was no default driver provided, we can't continue // But if there were no ops, and there was no default driver provided, we can't continue
// There were no ops, and it was because they were all filtered out // There were no ops, and it was because they were all filtered out
List<OpTemplate> unfilteredOps = opsDocList.getOps(false); OpTemplates unfilteredOps = templates.matching("",false);
if (!unfilteredOps.isEmpty()) { if (!unfilteredOps.isEmpty()) {
String message = "There were no active op templates with tag filter '" + tagfilter + "', since all " + unfilteredOps.size() + " were filtered out. Examine the session log for details"; String message = "There were no active op templates with tag filter '" + tagfilter + "', since all " + unfilteredOps.size() + " were filtered out. Examine the session log for details";
NBAdvisorOutput.test(message); NBAdvisorOutput.test(message);
//throw new BasicError(message); //throw new BasicError(message);
} }
if (defaultDriverAdapter instanceof SyntheticOpTemplateProvider sotp) { if (defaultDriverAdapter instanceof SyntheticOpTemplateProvider sotp) {
filteredOps = sotp.getSyntheticOpTemplates( filteredOps = sotp.getSyntheticOpTemplates(templates, this.activityDef.getParams());
opsDocList, this.activityDef.getParams());
Objects.requireNonNull(filteredOps); Objects.requireNonNull(filteredOps);
if (filteredOps.isEmpty()) { if (filteredOps.isEmpty()) {
throw new BasicError( throw new BasicError(
@@ -506,7 +468,7 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
@param seq @param seq
- The {@link OpSequence} to derive the defaults from - The {@link OpSequence} to derive the defaults from
*/ */
public synchronized void setDefaultsFromOpSequence(OpSequence<?> seq) { private synchronized void setDefaultsFromOpSequence(OpSequence<?> seq) {
Optional<String> strideOpt = getParams().getOptionalString("stride"); Optional<String> strideOpt = getParams().getOptionalString("stride");
if (strideOpt.isEmpty()) { if (strideOpt.isEmpty()) {
String stride = String.valueOf(seq.getSequence().length); String stride = String.valueOf(seq.getSequence().length);
@@ -552,9 +514,7 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
if (threads > activityDef.getCycleCount()) { if (threads > activityDef.getCycleCount()) {
threads = (int) activityDef.getCycleCount(); threads = (int) activityDef.getCycleCount();
logger.info( logger.info(
"setting threads to {} (auto) [10xCORES, cycle count limited]", "setting threads to {} (auto) [10xCORES, cycle count limited]", threads);
threads
);
} else { } else {
logger.info("setting threads to {} (auto) [10xCORES]", threads); logger.info("setting threads to {} (auto) [10xCORES]", threads);
} }
@@ -588,70 +548,71 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
} }
} }
/** // /**
Given a function that can create an op of type <O> from an OpTemplate, generate // Given a function that can create an op of type <O> from an OpTemplate, generate
an indexed sequence of ready to call operations. // an indexed sequence of ready to call operations.
<p> // <p>
This method uses the following conventions to derive the sequence: // This method uses the following conventions to derive the sequence:
//
<OL> // <OL>
<LI>If an 'op', 'stmt', or 'statement' parameter is provided, then it's value is // <LI>If an 'op', 'stmt', or 'statement' parameter is provided, then it's value is
taken as the only provided statement.</LI> // taken as the only provided statement.</LI>
<LI>If a 'yaml, or 'workload' parameter is provided, then the statements in that file // <LI>If a 'yaml, or 'workload' parameter is provided, then the statements in that file
are taken with their ratios </LI> // are taken with their ratios </LI>
<LI>Any provided tags filter is used to select only the op templates which have matching // <LI>Any provided tags filter is used to select only the op templates which have matching
tags. If no tags are provided, then all the found op templates are included.</LI> // tags. If no tags are provided, then all the found op templates are included.</LI>
<LI>The ratios and the 'seq' parameter are used to build a sequence of the ready operations, // <LI>The ratios and the 'seq' parameter are used to build a sequence of the ready operations,
where the sequence length is the sum of the ratios.</LI> // where the sequence length is the sum of the ratios.</LI>
</OL> // </OL>
@param <O> // @param <O>
A holder for an executable operation for the native driver used by this activity. // A holder for an executable operation for the native driver used by this activity.
@param opinit // @param opinit
A function to map an OpTemplate to the executable operation form required by // A function to map an OpTemplate to the executable operation form required by
the native driver for this activity. // the native driver for this activity.
@param defaultAdapter // @param defaultAdapter
The adapter which will be used for any op templates with no explicit adapter // The adapter which will be used for any op templates with no explicit adapter
@return The sequence of operations as determined by filtering and ratios // @return The sequence of operations as determined by filtering and ratios
*/ // */
@Deprecated(forRemoval = true) // @Deprecated(forRemoval = true)
protected <O> OpSequence<OpDispenser<? extends O>> createOpSequence( // protected <O> OpSequence<OpDispenser<? extends O>> createOpSequence(
Function<OpTemplate, OpDispenser<? extends O>> opinit, boolean strict, // Function<OpTemplate, OpDispenser<? extends O>> opinit, boolean strict,
DriverAdapter<?, ?> defaultAdapter // DriverAdapter<?, ?> defaultAdapter
) { // ) {
//
List<OpTemplate> stmts = loadOpTemplates(defaultAdapter, true, false); // List<OpTemplate> stmts = loadOpTemplates(defaultAdapter, true, false);
//
List<Long> ratios = new ArrayList<>(stmts.size()); // List<Long> ratios = new ArrayList<>(stmts.size());
//
for (OpTemplate opTemplate : stmts) { // for (OpTemplate opTemplate : stmts) {
long ratio = opTemplate.removeParamOrDefault("ratio", 1); // long ratio = opTemplate.removeParamOrDefault("ratio", 1);
ratios.add(ratio); // ratios.add(ratio);
} // }
//
SequencerType sequencerType = getParams().getOptionalString("seq").map( // SequencerType sequencerType = getParams().getOptionalString("seq").map(
SequencerType::valueOf).orElse(SequencerType.bucket); // SequencerType::valueOf).orElse(SequencerType.bucket);
//
SequencePlanner<OpDispenser<? extends O>> planner = new SequencePlanner<>(sequencerType); // SequencePlanner<OpDispenser<? extends O>> planner = new SequencePlanner<>(sequencerType);
//
try { // try {
for (int i = 0; i < stmts.size(); i++) { // for (int i = 0; i < stmts.size(); i++) {
long ratio = ratios.get(i); // long ratio = ratios.get(i);
OpTemplate optemplate = stmts.get(i); // OpTemplate optemplate = stmts.get(i);
OpDispenser<? extends O> driverSpecificReadyOp = opinit.apply(optemplate); // OpDispenser<? extends O> driverSpecificReadyOp = opinit.apply(optemplate);
if (strict) { // if (strict) {
optemplate.assertConsumed(); // optemplate.assertConsumed();
} // }
planner.addOp(driverSpecificReadyOp, ratio); // planner.addOp(driverSpecificReadyOp, ratio);
} // }
} catch (Exception e) { // } catch (Exception e) {
throw new OpConfigError(e.getMessage(), workloadSource, e); // throw new OpConfigError(e.getMessage(), workloadSource, e);
} // }
//
return planner.resolve(); // return planner.resolve();
} // }
protected OpsDocList loadStmtsDocList() {
/// TODO: Move this out, adjacent to [OpsLoader]
protected OpTemplates loadOpTemplates() {
OpsDocList opsDocs = null;
try { try {
String op = activityDef.getParams().getOptionalString("op").orElse(null); String op = activityDef.getParams().getOptionalString("op").orElse(null);
String stmt = activityDef.getParams().getOptionalString("stmt", "statement").orElse( String stmt = activityDef.getParams().getOptionalString("stmt", "statement").orElse(
@@ -661,37 +622,30 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
if ((op != null ? 1 : 0) + (stmt != null ? 1 : 0) + (workload != null ? 1 : 0) > 1) { if ((op != null ? 1 : 0) + (stmt != null ? 1 : 0) + (workload != null ? 1 : 0) > 1) {
throw new OpConfigError( throw new OpConfigError(
"Only op, statement, or workload may be provided, not more than one."); "Only op, statement, or workload may be provided, not more than one.");
} } else if (workload != null && OpsLoader.isJson(workload)) {
if (workload != null && OpsLoader.isJson(workload)) {
workloadSource = "commandline: (workload/json):" + workload; workloadSource = "commandline: (workload/json):" + workload;
return OpsLoader.loadString( opsDocs = OpsLoader.loadString(
workload, OpTemplateFormat.json, activityDef.getParams(), null); workload, OpTemplateFormat.json, activityDef.getParams(), null);
} else if (workload != null && OpsLoader.isYaml(workload)) { } else if (workload != null && OpsLoader.isYaml(workload)) {
workloadSource = "commandline: (workload/yaml):" + workload; workloadSource = "commandline: (workload/yaml):" + workload;
return OpsLoader.loadString( opsDocs= OpsLoader.loadString(
workload, OpTemplateFormat.yaml, activityDef.getParams(), null); workload, OpTemplateFormat.yaml, activityDef.getParams(), null);
} else if (workload != null) { } else if (workload != null) {
return OpsLoader.loadPath(workload, activityDef.getParams(), "activities"); opsDocs= OpsLoader.loadPath(workload, activityDef.getParams(), "activities");
} } else if (stmt != null) {
if (stmt != null) {
workloadSource = "commandline: (stmt/inline): '" + stmt + "'"; workloadSource = "commandline: (stmt/inline): '" + stmt + "'";
return OpsLoader.loadString( opsDocs= OpsLoader.loadString(
stmt, OpTemplateFormat.inline, activityDef.getParams(), null); stmt, OpTemplateFormat.inline, activityDef.getParams(), null);
} } else if (op != null && OpsLoader.isJson(op)) {
if (op != null && OpsLoader.isJson(op)) {
workloadSource = "commandline: (op/json): '" + op + "'"; workloadSource = "commandline: (op/json): '" + op + "'";
return OpsLoader.loadString( opsDocs= OpsLoader.loadString(
op, OpTemplateFormat.json, activityDef.getParams(), null); op, OpTemplateFormat.json, activityDef.getParams(), null);
} else if (op != null) { } else if (op != null) {
workloadSource = "commandline: (op/inline): '" + op + "'"; workloadSource = "commandline: (op/inline): '" + op + "'";
return OpsLoader.loadString( opsDocs= OpsLoader.loadString(
op, OpTemplateFormat.inline, activityDef.getParams(), null); op, OpTemplateFormat.inline, activityDef.getParams(), null);
} }
return OpsDocList.none(); return new OpTemplates(opsDocs);
} catch (Exception e) { } catch (Exception e) {
throw new OpConfigError("Error loading op templates: " + e, workloadSource, e); throw new OpConfigError("Error loading op templates: " + e, workloadSource, e);
@@ -747,10 +701,6 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
this, strideLimiterSource, spec); this, strideLimiterSource, spec);
} }
public void createOrUpdateCycleLimiter(SimRateSpec spec) {
cycleLimiterSource = ThreadLocalRateLimiters.createOrUpdate(this, cycleLimiterSource, spec);
}
/** /**
Get the current cycle rate limiter for this activity. Get the current cycle rate limiter for this activity.
The cycle rate limiter is used to throttle the rate at which The cycle rate limiter is used to throttle the rate at which
@@ -826,25 +776,10 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
return this.getActivityDef().getAlias().compareTo(o.getActivityDef().getAlias()); return this.getActivityDef().getAlias().compareTo(o.getActivityDef().getAlias());
} }
public void registerAutoCloseable(AutoCloseable closeable) { // public void registerAutoCloseable(AutoCloseable closeable) {
this.closeables.add(closeable); // this.closeables.add(closeable);
} // }
//
public synchronized PrintWriter getConsoleOut() {
if (null == console) {
this.console = new PrintWriter(System.out, false, StandardCharsets.UTF_8);
}
return this.console;
}
public synchronized InputStream getConsoleIn() {
return System.in;
}
public void setConsoleOut(PrintWriter writer) {
this.console = writer;
}
public synchronized ErrorMetrics getExceptionMetrics() { public synchronized ErrorMetrics getExceptionMetrics() {
if (null == this.errorMetrics) { if (null == this.errorMetrics) {
errorMetrics = new ErrorMetrics(this); errorMetrics = new ErrorMetrics(this);
@@ -857,11 +792,6 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
return getActivityDef().getAlias(); return getActivityDef().getAlias();
} }
public int getHdrDigits() {
return getComponentProp("hdr_digits").map(Integer::parseInt).orElse(3);
}
@Override @Override
public Motor getMotor(ActivityDef activityDef, int slot) { public Motor getMotor(ActivityDef activityDef, int slot) {
return new CoreMotor(this, slot, getInput(), getAction(), getOutput()); return new CoreMotor(this, slot, getInput(), getAction(), getOutput());
@@ -885,4 +815,10 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
// TODO: Implement this as optional, only composing the optional behavior if required // TODO: Implement this as optional, only composing the optional behavior if required
return null; return null;
} }
private void createOrUpdateCycleLimiter(SimRateSpec spec) {
cycleLimiterSource = ThreadLocalRateLimiters.createOrUpdate(this, cycleLimiterSource, spec);
}
} }

View File

@@ -0,0 +1,63 @@
package io.nosqlbench.engine.api.activityimpl.uniform;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplate;
import io.nosqlbench.adapters.api.activityconfig.yaml.OpTemplates;
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.activityimpl.uniform.Space;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.CycleOp;
import io.nosqlbench.nb.api.errors.OpConfigError;
import io.nosqlbench.nb.api.tagging.TagFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
/// TODO: Auto-inject the default driver name into any op that doesn't have it set
///
/// ## Requirements for core
/// * All lookups must be lazy init
/// * All lookups must be cached
/// * All cache state must be extractable as plan
///
/// ## Requirements for callers
/// * Callers must be able to look up an op template by tag filter
/// * Callers must be able to look up a parsed op by tag filter
public class OpResolver {
private OpTemplates opTemplates;
private final Supplier<OpTemplates> optSupplier;
List<DriverAdapter<CycleOp<?>, Space>> adapterlist = new ArrayList<>();
public OpResolver(Supplier<OpTemplates> optSupplier) {
this.optSupplier = optSupplier;
}
/// Find a required op template matching a tag filter
public synchronized OpTemplate findOne(String tagFilter) {
return findOneOptional(tagFilter).orElseThrow(
() -> new OpConfigError("No op found for " + tagFilter));
}
private synchronized void load() {
if (opTemplates==null) {
opTemplates=optSupplier.get();
}
}
/// Find an optional op template matching a tag filter
public synchronized Optional<OpTemplate> findOneOptional(String tagFilter) {
List<OpTemplate> matching = lookup(tagFilter);
if (matching.size() > 1) {
throw new OpConfigError(
"Found more than one op templates with the tag filter: " + tagFilter);
}
return matching.size() == 1 ? Optional.of(matching.get(0)) : Optional.empty();
}
/// Find any op templates matching a tag filter
public synchronized List<OpTemplate> lookup(String tagFilter) {
load();
TagFilter tf = new TagFilter(tagFilter);
return opTemplates.stream().filter(tf::matchesTagged).toList();
}
}