mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
naming: use ParsedOp instead of ParsedCommand
This commit is contained in:
parent
9763dd0be7
commit
828ec0252d
@ -9,7 +9,7 @@ import io.nosqlbench.adapter.cqld4.processors.CqlFieldCaptureProcessor;
|
|||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.activityimpl.OpMapper;
|
import io.nosqlbench.engine.api.activityimpl.OpMapper;
|
||||||
import io.nosqlbench.engine.api.activityimpl.uniform.DriverSpaceCache;
|
import io.nosqlbench.engine.api.activityimpl.uniform.DriverSpaceCache;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.config.params.ParamsParser;
|
import io.nosqlbench.nb.api.config.params.ParamsParser;
|
||||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
import io.nosqlbench.nb.api.errors.BasicError;
|
||||||
@ -30,7 +30,7 @@ public class Cqld4OpMapper implements OpMapper<Cqld4Op> {
|
|||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpDispenser<Cqld4Op> apply(ParsedCommand cmd) {
|
public OpDispenser<Cqld4Op> apply(ParsedOp cmd) {
|
||||||
|
|
||||||
ParsedTemplate stmtTpl = cmd.getStmtAsTemplate().orElseThrow(() -> new BasicError(
|
ParsedTemplate stmtTpl = cmd.getStmtAsTemplate().orElseThrow(() -> new BasicError(
|
||||||
"No statement was found in the op template:" + cmd
|
"No statement was found in the op template:" + cmd
|
||||||
|
@ -3,15 +3,15 @@ package io.nosqlbench.adapter.cqld4.opdispensers;
|
|||||||
import com.datastax.oss.driver.api.core.CqlSession;
|
import com.datastax.oss.driver.api.core.CqlSession;
|
||||||
import io.nosqlbench.adapter.cqld4.Cqld4Op;
|
import io.nosqlbench.adapter.cqld4.Cqld4Op;
|
||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
import io.nosqlbench.nb.api.errors.BasicError;
|
||||||
|
|
||||||
public class CqlD4PreparedBatchOpDispenser implements OpDispenser<Cqld4Op> {
|
public class CqlD4PreparedBatchOpDispenser implements OpDispenser<Cqld4Op> {
|
||||||
|
|
||||||
private final CqlSession session;
|
private final CqlSession session;
|
||||||
private final ParsedCommand cmd;
|
private final ParsedOp cmd;
|
||||||
|
|
||||||
public CqlD4PreparedBatchOpDispenser(CqlSession session, ParsedCommand cmd) {
|
public CqlD4PreparedBatchOpDispenser(CqlSession session, ParsedOp cmd) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ package io.nosqlbench.adapter.cqld4.opdispensers;
|
|||||||
import com.datastax.oss.driver.api.core.CqlSession;
|
import com.datastax.oss.driver.api.core.CqlSession;
|
||||||
import io.nosqlbench.adapter.cqld4.Cqld4Op;
|
import io.nosqlbench.adapter.cqld4.Cqld4Op;
|
||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
|
|
||||||
public class Cqld4BatchStatementDispenser implements OpDispenser<Cqld4Op> {
|
public class Cqld4BatchStatementDispenser implements OpDispenser<Cqld4Op> {
|
||||||
private final CqlSession session;
|
private final CqlSession session;
|
||||||
private final ParsedCommand cmd;
|
private final ParsedOp cmd;
|
||||||
|
|
||||||
public Cqld4BatchStatementDispenser(CqlSession session, ParsedCommand cmd) {
|
public Cqld4BatchStatementDispenser(CqlSession session, ParsedOp cmd) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import io.nosqlbench.adapter.cqld4.Cqld4OpMetrics;
|
|||||||
import io.nosqlbench.adapter.cqld4.optypes.Cqld4PreparedStatement;
|
import io.nosqlbench.adapter.cqld4.optypes.Cqld4PreparedStatement;
|
||||||
import io.nosqlbench.adapter.cqld4.RSProcessors;
|
import io.nosqlbench.adapter.cqld4.RSProcessors;
|
||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.virtdata.core.templates.ParsedTemplate;
|
import io.nosqlbench.virtdata.core.templates.ParsedTemplate;
|
||||||
|
|
||||||
import java.util.function.LongFunction;
|
import java.util.function.LongFunction;
|
||||||
@ -24,7 +24,7 @@ public class Cqld4PreparedStmtDispenser implements OpDispenser<Cqld4Op> {
|
|||||||
private final Cqld4OpMetrics metrics;
|
private final Cqld4OpMetrics metrics;
|
||||||
private final RSProcessors processors;
|
private final RSProcessors processors;
|
||||||
|
|
||||||
public Cqld4PreparedStmtDispenser(CqlSession session, ParsedCommand cmd, RSProcessors processors) {
|
public Cqld4PreparedStmtDispenser(CqlSession session, ParsedOp cmd, RSProcessors processors) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.processors = processors;
|
this.processors = processors;
|
||||||
|
|
||||||
|
@ -6,17 +6,17 @@ import io.nosqlbench.adapter.cqld4.Cqld4Op;
|
|||||||
import io.nosqlbench.adapter.cqld4.Cqld4OpMetrics;
|
import io.nosqlbench.adapter.cqld4.Cqld4OpMetrics;
|
||||||
import io.nosqlbench.adapter.cqld4.optypes.Cqld4SimpleCqlStatement;
|
import io.nosqlbench.adapter.cqld4.optypes.Cqld4SimpleCqlStatement;
|
||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
|
|
||||||
public class Cqld4SimpleCqlStmtDispenser implements OpDispenser<Cqld4Op> {
|
public class Cqld4SimpleCqlStmtDispenser implements OpDispenser<Cqld4Op> {
|
||||||
|
|
||||||
private final CqlSession session;
|
private final CqlSession session;
|
||||||
private final ParsedCommand cmd;
|
private final ParsedOp cmd;
|
||||||
private final int maxpages;
|
private final int maxpages;
|
||||||
private final boolean retryreplace;
|
private final boolean retryreplace;
|
||||||
private final Cqld4OpMetrics metrics;
|
private final Cqld4OpMetrics metrics;
|
||||||
|
|
||||||
public Cqld4SimpleCqlStmtDispenser(CqlSession session, ParsedCommand cmd) {
|
public Cqld4SimpleCqlStmtDispenser(CqlSession session, ParsedOp cmd) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
this.maxpages = cmd.getStaticConfigOr("maxpages",1);
|
this.maxpages = cmd.getStaticConfigOr("maxpages",1);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.nosqlbench.engine.api.activityimpl;
|
package io.nosqlbench.engine.api.activityimpl;
|
||||||
|
|
||||||
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ import java.util.function.Function;
|
|||||||
* </hr>
|
* </hr>
|
||||||
* <h2>Implementation Strategy</h2>
|
* <h2>Implementation Strategy</h2>
|
||||||
* <p>
|
* <p>
|
||||||
* A view of an op template is provided in the {@link ParsedCommand} API. This allows
|
* A view of an op template is provided in the {@link ParsedOp} API. This allows
|
||||||
* you to examine the fields provided by users. It also lets you see which
|
* you to examine the fields provided by users. It also lets you see which
|
||||||
* of these fields are defined as dynamic and which are simply static values.
|
* of these fields are defined as dynamic and which are simply static values.
|
||||||
* When multiple types of operations are supported for a driver adapter, you must decide
|
* When multiple types of operations are supported for a driver adapter, you must decide
|
||||||
@ -62,16 +62,16 @@ import java.util.function.Function;
|
|||||||
* to hold all the details for executing an operation,
|
* to hold all the details for executing an operation,
|
||||||
* generally something that implements {@link Runnable}.
|
* generally something that implements {@link Runnable}.
|
||||||
*/
|
*/
|
||||||
public interface OpMapper<T extends Op> extends Function<ParsedCommand, OpDispenser<T>> {
|
public interface OpMapper<T extends Op> extends Function<ParsedOp, OpDispenser<T>> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interrogate the parsed command, and provide a new
|
* Interrogate the parsed command, and provide a new
|
||||||
*
|
*
|
||||||
* @param cmd The {@link ParsedCommand} which is the parsed version of the user-provided op template.
|
* @param cmd The {@link ParsedOp} which is the parsed version of the user-provided op template.
|
||||||
* This contains all the fields provided by the user, as well as explicit knowledge of
|
* This contains all the fields provided by the user, as well as explicit knowledge of
|
||||||
* which ones are static and dynamic.
|
* which ones are static and dynamic.
|
||||||
* @return An OpDispenser which can be used to synthesize real operations.
|
* @return An OpDispenser which can be used to synthesize real operations.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
OpDispenser<T> apply(ParsedCommand cmd);
|
OpDispenser<T> apply(ParsedOp cmd);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.nosqlbench.engine.api.activityimpl.uniform;
|
|||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.activityimpl.OpMapper;
|
import io.nosqlbench.engine.api.activityimpl.OpMapper;
|
||||||
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -36,7 +36,7 @@ public interface DriverAdapter<R extends Op, S> {
|
|||||||
* <p>
|
* <p>
|
||||||
* <H2>Op Mapping</H2>
|
* <H2>Op Mapping</H2>
|
||||||
* An Op Mapper is a function which can look at the parsed
|
* An Op Mapper is a function which can look at the parsed
|
||||||
* fields in a {@link ParsedCommand} and create an OpDispenser.
|
* fields in a {@link ParsedOp} and create an OpDispenser.
|
||||||
* An OpDispenser is a function that will produce a special
|
* An OpDispenser is a function that will produce a special
|
||||||
* type {@link R} that this DriverAdapter implements as its
|
* type {@link R} that this DriverAdapter implements as its
|
||||||
* op implementation.</p>
|
* op implementation.</p>
|
||||||
@ -63,7 +63,7 @@ public interface DriverAdapter<R extends Op, S> {
|
|||||||
* <p>
|
* <p>
|
||||||
* <H2>A note on implementation strategy:</H2>
|
* <H2>A note on implementation strategy:</H2>
|
||||||
* Generally speaking, implementations of this method should interrogate the op fields
|
* Generally speaking, implementations of this method should interrogate the op fields
|
||||||
* in the ParsedCommand and return an OpDispenser that matches the user's intentions.
|
* in the ParsedOp and return an OpDispenser that matches the user's intentions.
|
||||||
* This can be based on something explicit, like the value of a {@code type} field,
|
* This can be based on something explicit, like the value of a {@code type} field,
|
||||||
* or it can be based on whether certain fields are present or not. Advanced implementations
|
* or it can be based on whether certain fields are present or not. Advanced implementations
|
||||||
* might take into account which fields are provided as static values and which are
|
* might take into account which fields are provided as static values and which are
|
||||||
|
@ -1,438 +0,0 @@
|
|||||||
package io.nosqlbench.engine.api.templating;
|
|
||||||
|
|
||||||
import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate;
|
|
||||||
import io.nosqlbench.engine.api.templating.binders.ArrayBinder;
|
|
||||||
import io.nosqlbench.engine.api.templating.binders.ListBinder;
|
|
||||||
import io.nosqlbench.engine.api.templating.binders.OrderedMapBinder;
|
|
||||||
import io.nosqlbench.nb.api.config.standard.NBConfigError;
|
|
||||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
|
||||||
import io.nosqlbench.nb.api.config.standard.NBTypeConverter;
|
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
|
||||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
|
||||||
import io.nosqlbench.virtdata.core.bindings.DataMapper;
|
|
||||||
import io.nosqlbench.virtdata.core.bindings.VirtData;
|
|
||||||
import io.nosqlbench.virtdata.core.templates.BindPoint;
|
|
||||||
import io.nosqlbench.virtdata.core.templates.CapturePoint;
|
|
||||||
import io.nosqlbench.virtdata.core.templates.ParsedTemplate;
|
|
||||||
import io.nosqlbench.virtdata.core.templates.StringBindings;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.LongFunction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse an OpTemplate into a ParsedCommand, which can dispense object maps
|
|
||||||
*/
|
|
||||||
public class ParsedCommand implements LongFunction<Map<String, ?>> {
|
|
||||||
|
|
||||||
private final static Logger logger = LogManager.getLogger(ParsedCommand.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The fields which are statically assigned
|
|
||||||
**/
|
|
||||||
private final Map<String, Object> statics = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The fields which are dynamic, and must be realized via functions.
|
|
||||||
* This map contains keys which identify the field names, and values, which may be null or undefined.
|
|
||||||
*/
|
|
||||||
private final Map<String, LongFunction<?>> dynamics = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The names of payload values in the result of the operation which should be saved.
|
|
||||||
* The keys in this map represent the name of the value as it would be found in the native
|
|
||||||
* representation of a result. If the values are defined, then each one represents the name
|
|
||||||
* that the found value should be saved as instead of the original name.
|
|
||||||
*/
|
|
||||||
private final List<List<CapturePoint>> captures = new ArrayList<>();
|
|
||||||
private final int mapsize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A prototype of the fully generated map, to be used as the starting point
|
|
||||||
* when rendering the full map with dynamic values.
|
|
||||||
*/
|
|
||||||
private final LinkedHashMap<String, Object> protomap = new LinkedHashMap<>();
|
|
||||||
private final OpTemplate ot;
|
|
||||||
private final NBConfiguration acfg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a parsed command from an Op template.
|
|
||||||
*
|
|
||||||
* @param ot An OpTemplate representing an operation to be performed in a native driver.
|
|
||||||
* @param acfg The activity configuration, used for reading config parameters
|
|
||||||
*/
|
|
||||||
public ParsedCommand(OpTemplate ot, NBConfiguration acfg) {
|
|
||||||
this(ot, acfg, List.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a parsed command from an Op template. This version is exactly like
|
|
||||||
* {@link ParsedCommand(OpTemplate,NBConfiguration)} except that it allows
|
|
||||||
* preprocessors. Preprocessors are all applied to the the op template before
|
|
||||||
* it is applied to the parsed command fields, allowing you to combine or destructure
|
|
||||||
* fields from more tha one representation into a single canonical representation
|
|
||||||
* for processing.
|
|
||||||
*
|
|
||||||
* @param ot The OpTemplate as provided by a user via YAML, JSON, or API (data structure)
|
|
||||||
* @param acfg The activity configuration, used to resolve nested config parameters
|
|
||||||
* @param preprocessors Map->Map transformers.
|
|
||||||
*/
|
|
||||||
public ParsedCommand(OpTemplate ot, NBConfiguration acfg, List<Function<Map<String, Object>, Map<String, Object>>> preprocessors) {
|
|
||||||
this.ot = ot;
|
|
||||||
this.acfg = acfg;
|
|
||||||
|
|
||||||
Map<String, Object> map = ot.getOp().orElseThrow();
|
|
||||||
for (Function<Map<String, Object>, Map<String, Object>> preprocessor : preprocessors) {
|
|
||||||
map = preprocessor.apply(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
applyTemplateFields(map, ot.getBindings());
|
|
||||||
mapsize = statics.size() + dynamics.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For now, we only allow bind points to reference bindings, not other op template
|
|
||||||
// fields. This seems like the saner and less confusing approach, so implementing
|
|
||||||
// op field references should be left until it is requested if at all
|
|
||||||
private void applyTemplateFields(Map<String, Object> map, Map<String, String> bindings) {
|
|
||||||
map.forEach((k, v) -> {
|
|
||||||
if (v instanceof CharSequence) {
|
|
||||||
ParsedTemplate pt = ParsedTemplate.of(((CharSequence) v).toString(), bindings);
|
|
||||||
this.captures.add(pt.getCaptures());
|
|
||||||
switch (pt.getType()) {
|
|
||||||
case literal:
|
|
||||||
statics.put(k, ((CharSequence) v).toString());
|
|
||||||
protomap.put(k, ((CharSequence) v).toString());
|
|
||||||
break;
|
|
||||||
case bindref:
|
|
||||||
String spec = pt.asBinding().orElseThrow().getBindspec();
|
|
||||||
Optional<DataMapper<Object>> mapper = VirtData.getOptionalMapper(spec);
|
|
||||||
dynamics.put(k, mapper.orElseThrow());
|
|
||||||
protomap.put(k, null);
|
|
||||||
break;
|
|
||||||
case concat:
|
|
||||||
StringBindings sb = new StringBindings(pt);
|
|
||||||
dynamics.put(k, sb);
|
|
||||||
protomap.put(k, null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Eventually, nested and mixed static dynamic structure could be supported, but
|
|
||||||
// it would be complex to implement and also not that efficient, so let's just copy
|
|
||||||
// structure for now
|
|
||||||
statics.put(k, v);
|
|
||||||
protomap.put(k, v);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return ot.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Object> getStaticPrototype() {
|
|
||||||
return statics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, LongFunction<?>> getDynamicPrototype() {
|
|
||||||
return dynamics;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> apply(long value) {
|
|
||||||
LinkedHashMap<String, Object> map = new LinkedHashMap<>(protomap);
|
|
||||||
dynamics.forEach((k, v) -> {
|
|
||||||
map.put(k, v.apply(value));
|
|
||||||
});
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefinedDynamic(String field) {
|
|
||||||
return dynamics.containsKey(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param field The field name to look for in the static field map.
|
|
||||||
* @return true if and only if the named field is present in the static field map.
|
|
||||||
*/
|
|
||||||
public boolean isDefinedStatic(String field) {
|
|
||||||
return statics.containsKey(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefinedStatic(String field, Class<?> type) {
|
|
||||||
return statics.containsKey(field) && type.isAssignableFrom(field.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param fields Names of fields to look for in the static field map.
|
|
||||||
* @return true if and only if all provided field names are present in the static field map.
|
|
||||||
*/
|
|
||||||
public boolean isDefinedStaticAll(String... fields) {
|
|
||||||
for (String field : fields) {
|
|
||||||
if (!statics.containsKey(field)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the static value for the provided name, cast to the required type.
|
|
||||||
*
|
|
||||||
* @param field Name of the field to get
|
|
||||||
* @param classOfT The type of the field to return. If actual type is not compatible to a cast to this type, then a
|
|
||||||
* casting error will be thrown.
|
|
||||||
* @param <T> The parameter type of the return type, used at compile time only to qualify asserted return type
|
|
||||||
* @return A value of type T, or null
|
|
||||||
*/
|
|
||||||
public <T> T getStaticValue(String field, Class<T> classOfT) {
|
|
||||||
return (T) statics.get(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the static value for the provided name, cast to the required type, where the type is inferred
|
|
||||||
* from the calling context.
|
|
||||||
*
|
|
||||||
* @param field Name of the field to get
|
|
||||||
* @param <T> The parameter type of the return type. used at compile time only to quality return type.
|
|
||||||
* @return A value of type T, or null
|
|
||||||
*/
|
|
||||||
public <T> T getStaticValue(String field) {
|
|
||||||
return (T) statics.get(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<ParsedTemplate> getStmtAsTemplate() {
|
|
||||||
return ot.getParsed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the named static field value, or return the provided default, but throw an exception if
|
|
||||||
* the named field is dynamic.
|
|
||||||
*
|
|
||||||
* @param name The name of the field value to return.
|
|
||||||
* @param defaultValue A value to return if the named value is not present in static nor dynamic fields.
|
|
||||||
* @param <T> The type of the field to return.
|
|
||||||
* @return The value
|
|
||||||
* @throws RuntimeException if the field name is only present in the dynamic fields.
|
|
||||||
*/
|
|
||||||
public <T> T getStaticValueOr(String name, T defaultValue) {
|
|
||||||
if (statics.containsKey(name)) {
|
|
||||||
return (T) statics.get(name);
|
|
||||||
} else if (dynamics.containsKey(name)) {
|
|
||||||
throw new BasicError("static field '" + name + "' was defined dynamically. This may be supportable if the driver developer" +
|
|
||||||
"updates the op mapper to support this field as a dynamic field, but it is not yet supported.");
|
|
||||||
} else {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the specified parameter by the user using the defined field which is closest to the op
|
|
||||||
* template. This is the standard way of getting parameter values which can be specified at the
|
|
||||||
* op template, op param, or activity level.
|
|
||||||
*
|
|
||||||
* @param name The name of the configuration param
|
|
||||||
* @param defaultValue the default value to return if the value is not defined anywhere in
|
|
||||||
* (op fields, op params, activity params)
|
|
||||||
* @param <T> The type of the value to return
|
|
||||||
* @return A configuration value
|
|
||||||
* @throws io.nosqlbench.nb.api.config.standard.NBConfigError if the named field is defined dynamically,
|
|
||||||
* as in this case, it is presumed that the parameter is not supported unless it is defined statically.
|
|
||||||
*/
|
|
||||||
public <T> T getStaticConfigOr(String name, T defaultValue) {
|
|
||||||
if (statics.containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(statics.get(name), defaultValue);
|
|
||||||
} else if (ot.getParams().containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(ot.getParams().get(name), defaultValue);
|
|
||||||
} else if (acfg.getMap().containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(acfg.get("name"), defaultValue);
|
|
||||||
} else if (dynamics.containsKey(name)) {
|
|
||||||
throw new NBConfigError("static config field '" + name + "' was defined dynamically. This may be supportable if the driver developer" +
|
|
||||||
"updates the op mapper to support this field as a dynamic field, but it is not yet supported.");
|
|
||||||
} else {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> Optional<T> getOptionalStaticConfig(String name, Class<T> type) {
|
|
||||||
if (statics.containsKey(name)) {
|
|
||||||
return Optional.of(NBTypeConverter.convert(statics.get(name), type));
|
|
||||||
} else if (ot.getParams().containsKey(name)) {
|
|
||||||
return Optional.of(NBTypeConverter.convert(ot.getParams().get(name), type));
|
|
||||||
} else if (acfg.getMap().containsKey(name)) {
|
|
||||||
return Optional.of(NBTypeConverter.convert(acfg.get("name"), type));
|
|
||||||
} else if (dynamics.containsKey("name")) {
|
|
||||||
throw new NBConfigError("static config field '" + name + "' was defined dynamically. This may be supportable if the driver developer" +
|
|
||||||
"updates the op mapper to support this field as a dynamic field, but it is not yet supported.");
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Works exactly like {@link #getStaticConfigOr(String, Object)}, except that dynamic values
|
|
||||||
* at the op field level will be generated on a per-input basis. This is a shortcut method for
|
|
||||||
* allowing configuration values to be accessed dynamically where it makes sense.
|
|
||||||
*/
|
|
||||||
public <T> T getConfigOr(String name, T defaultValue, long input) {
|
|
||||||
if (statics.containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(statics.get(name), defaultValue);
|
|
||||||
} else if (dynamics.containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(dynamics.get(name).apply(input), defaultValue);
|
|
||||||
} else if (ot.getParams().containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(ot.getParams().get(name), defaultValue);
|
|
||||||
} else if (acfg.getMap().containsKey(name)) {
|
|
||||||
return NBTypeConverter.convertOr(acfg.get("name"), defaultValue);
|
|
||||||
} else return defaultValue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an optional value for the named field. This is an {@link Optional} form of {@link #getStaticValue}.
|
|
||||||
*
|
|
||||||
* @param field Name of the field to get
|
|
||||||
* @param classOfT The type of field to return. If the actual type is not compatible to a cast to this type,
|
|
||||||
* then a casting error will be thrown.
|
|
||||||
* @param <T> The parameter type of the return
|
|
||||||
* @return An optional value, empty unless the named value is defined in the static field map.
|
|
||||||
*/
|
|
||||||
public <T> Optional<T> getStaticValueOptionally(String field, Class<T> classOfT) {
|
|
||||||
return Optional.ofNullable(getStaticValue(field, classOfT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> Optional<T> getStaticValueOptionally(String field) {
|
|
||||||
return Optional.ofNullable(getStaticValue(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the named field value for a given long input. This uses parameter type inference -- The casting
|
|
||||||
* to the return type will be based on the type of any assignment or casting on the caller's side.
|
|
||||||
* Thus, if the actual type is not compatable to a cast to the needed return type, a casting error will
|
|
||||||
* be thrown.
|
|
||||||
*
|
|
||||||
* @param field The name of the field to get.
|
|
||||||
* @param input The seed value, or cycle value for which to generate the value.
|
|
||||||
* @param <T> The parameter type of the returned value. Inferred from usage context.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public <T> T get(String field, long input) {
|
|
||||||
if (statics.containsKey(field)) {
|
|
||||||
return (T) statics.get(field);
|
|
||||||
}
|
|
||||||
if (dynamics.containsKey(field)) {
|
|
||||||
return (T) dynamics.get(field).apply(input);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the map of all fields for the given input cycle.
|
|
||||||
*
|
|
||||||
* @param l seed value, cycle number, input...
|
|
||||||
* @return A map of named objects
|
|
||||||
*/
|
|
||||||
public Map<String, Object> getMap(long l) {
|
|
||||||
return apply(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getDefinedNames() {
|
|
||||||
HashSet<String> nameSet = new HashSet<>(statics.keySet());
|
|
||||||
nameSet.addAll(dynamics.keySet());
|
|
||||||
return nameSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <V> LongFunction<V> getAsFunctionOr(String name, V defaultValue) {
|
|
||||||
if (isDefinedStatic(name)) {
|
|
||||||
V value = getStaticValue(name);
|
|
||||||
return l -> value;
|
|
||||||
} else if (isDefinedDynamic(name)) {
|
|
||||||
return l -> get(name, l);
|
|
||||||
} else {
|
|
||||||
return l -> defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefined(String field) {
|
|
||||||
return statics.containsKey(field) || dynamics.containsKey(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefinedAll(String... fields) {
|
|
||||||
for (String field : fields) {
|
|
||||||
if (!statics.containsKey(field) && !dynamics.containsKey(field)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requireStaticFields(String... fields) {
|
|
||||||
for (String field : fields) {
|
|
||||||
if (!statics.containsKey(field)) {
|
|
||||||
Set<String> missing = new HashSet<>();
|
|
||||||
for (String readoutfield : fields) {
|
|
||||||
if (!statics.containsKey(readoutfield)) {
|
|
||||||
missing.add(readoutfield);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new OpConfigError("Fields " + missing + " are required to be defined with static values for this type of operation.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<List<Object>> newListBinder(String... fields) {
|
|
||||||
return new ListBinder(this, fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<List<Object>> newListBinder(List<String> fields) {
|
|
||||||
return new ListBinder(this, fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<Map<String, Object>> newOrderedMapBinder(String... fields) {
|
|
||||||
return new OrderedMapBinder(this, fields);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<Object[]> newArrayBinder(String... fields) {
|
|
||||||
return new ArrayBinder(this, fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<Object[]> newArrayBinder(List<String> fields) {
|
|
||||||
return new ArrayBinder(this, fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<Object[]> newArrayBinderFromBindPoints(List<BindPoint> bindPoints) {
|
|
||||||
return new ArrayBinder(bindPoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongFunction<?> getMapper(String field) {
|
|
||||||
LongFunction<?> mapper = dynamics.get(field);
|
|
||||||
return mapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return this.mapsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUndefined(String field) {
|
|
||||||
return !(statics.containsKey(field) || dynamics.containsKey(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ParsedCommand parseField(String srcField, Function<String,Map<String,Object>> parser) {
|
|
||||||
//
|
|
||||||
// String field = Optional.ofNullable(statics.get(srcField))
|
|
||||||
// .filter(o -> o instanceof CharSequence)
|
|
||||||
// .map(Object::toString)
|
|
||||||
// .orElseThrow();
|
|
||||||
//
|
|
||||||
// Map<String, Object> newFields = parser.apply(field);
|
|
||||||
// apply(newFields)
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
package io.nosqlbench.engine.api.templating.binders;
|
package io.nosqlbench.engine.api.templating.binders;
|
||||||
|
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
import io.nosqlbench.nb.api.errors.OpConfigError;
|
||||||
import io.nosqlbench.virtdata.core.bindings.DataMapper;
|
import io.nosqlbench.virtdata.core.bindings.DataMapper;
|
||||||
import io.nosqlbench.virtdata.core.bindings.VirtData;
|
import io.nosqlbench.virtdata.core.bindings.VirtData;
|
||||||
@ -17,7 +17,7 @@ public class ArrayBinder implements LongFunction<Object[]> {
|
|||||||
private final LongFunction<?>[] mapperary;
|
private final LongFunction<?>[] mapperary;
|
||||||
private final int[] dindexes;
|
private final int[] dindexes;
|
||||||
|
|
||||||
public ArrayBinder(ParsedCommand cmd, String[] fields) {
|
public ArrayBinder(ParsedOp cmd, String[] fields) {
|
||||||
this.protoary = new Object[fields.length];
|
this.protoary = new Object[fields.length];
|
||||||
this.mapperary = new LongFunction<?>[fields.length];
|
this.mapperary = new LongFunction<?>[fields.length];
|
||||||
int[] indexes = new int[fields.length];
|
int[] indexes = new int[fields.length];
|
||||||
@ -25,7 +25,7 @@ public class ArrayBinder implements LongFunction<Object[]> {
|
|||||||
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
for (int i = 0; i < fields.length; i++) {
|
||||||
String field = fields[i];
|
String field = fields[i];
|
||||||
if (cmd.isDefinedStatic(field)) {
|
if (cmd.isStatic(field)) {
|
||||||
protoary[i] = cmd.getStaticValue(field);
|
protoary[i] = cmd.getStaticValue(field);
|
||||||
} else if (cmd.isDefinedDynamic(field)) {
|
} else if (cmd.isDefinedDynamic(field)) {
|
||||||
mapperary[i] = cmd.getMapper(field);
|
mapperary[i] = cmd.getMapper(field);
|
||||||
@ -37,7 +37,7 @@ public class ArrayBinder implements LongFunction<Object[]> {
|
|||||||
this.dindexes = Arrays.copyOf(indexes, nextIndex);
|
this.dindexes = Arrays.copyOf(indexes, nextIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayBinder(ParsedCommand cmd, List<String> fields) {
|
public ArrayBinder(ParsedOp cmd, List<String> fields) {
|
||||||
this(cmd, fields.toArray(new String[0]));
|
this(cmd, fields.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.nosqlbench.engine.api.templating.binders;
|
package io.nosqlbench.engine.api.templating.binders;
|
||||||
|
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
import io.nosqlbench.nb.api.errors.OpConfigError;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -14,7 +14,7 @@ public class ListBinder implements LongFunction<List<Object>> {
|
|||||||
private final ArrayList<LongFunction<?>> mapperlist;
|
private final ArrayList<LongFunction<?>> mapperlist;
|
||||||
private final int[] dindexes;
|
private final int[] dindexes;
|
||||||
|
|
||||||
public ListBinder(ParsedCommand cmd, String... fields) {
|
public ListBinder(ParsedOp cmd, String... fields) {
|
||||||
this.protolist = new ArrayList<>(fields.length);
|
this.protolist = new ArrayList<>(fields.length);
|
||||||
this.mapperlist = new ArrayList<>(fields.length);
|
this.mapperlist = new ArrayList<>(fields.length);
|
||||||
int[] indexes = new int[fields.length];
|
int[] indexes = new int[fields.length];
|
||||||
@ -22,7 +22,7 @@ public class ListBinder implements LongFunction<List<Object>> {
|
|||||||
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
for (int i = 0; i < fields.length; i++) {
|
||||||
String field = fields[i];
|
String field = fields[i];
|
||||||
if (cmd.isDefinedStatic(field)) {
|
if (cmd.isStatic(field)) {
|
||||||
protolist.add(cmd.getStaticValue(field));
|
protolist.add(cmd.getStaticValue(field));
|
||||||
mapperlist.add(null);
|
mapperlist.add(null);
|
||||||
} else if (cmd.isDefinedDynamic(field)) {
|
} else if (cmd.isDefinedDynamic(field)) {
|
||||||
@ -36,7 +36,7 @@ public class ListBinder implements LongFunction<List<Object>> {
|
|||||||
this.dindexes = Arrays.copyOf(indexes,lastIndex);
|
this.dindexes = Arrays.copyOf(indexes,lastIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListBinder(ParsedCommand cmd, List<String> fields) {
|
public ListBinder(ParsedOp cmd, List<String> fields) {
|
||||||
this(cmd,fields.toArray(new String[0]));
|
this(cmd,fields.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.nosqlbench.engine.api.templating.binders;
|
package io.nosqlbench.engine.api.templating.binders;
|
||||||
|
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
import io.nosqlbench.nb.api.errors.OpConfigError;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -13,9 +13,9 @@ public class OrderedMapBinder implements LongFunction<Map<String, Object>> {
|
|||||||
private final Map<String,Object> protomap = new LinkedHashMap<>();
|
private final Map<String,Object> protomap = new LinkedHashMap<>();
|
||||||
private final Map<String,LongFunction<?>> bindermap = new HashMap<>();
|
private final Map<String,LongFunction<?>> bindermap = new HashMap<>();
|
||||||
|
|
||||||
public OrderedMapBinder(ParsedCommand cmd, String... fields) {
|
public OrderedMapBinder(ParsedOp cmd, String... fields) {
|
||||||
for (String field : fields) {
|
for (String field : fields) {
|
||||||
if (cmd.isDefinedStatic(field)) {
|
if (cmd.isStatic(field)) {
|
||||||
protomap.put(field,cmd.getStaticValue(field));
|
protomap.put(field,cmd.getStaticValue(field));
|
||||||
} else if (cmd.isDefinedDynamic(field)) {
|
} else if (cmd.isDefinedDynamic(field)) {
|
||||||
bindermap.put(field,cmd.getMapper(field));
|
bindermap.put(field,cmd.getMapper(field));
|
||||||
|
@ -61,7 +61,7 @@ which is the same across all driver types that can be used with NoSQLBench.
|
|||||||
|
|
||||||
The Op Templates which are provided by users are normalized by NoSQLBench into a standard
|
The Op Templates which are provided by users are normalized by NoSQLBench into a standard
|
||||||
representation that is used within the op mapping and synthesis steps. This representation is
|
representation that is used within the op mapping and synthesis steps. This representation is
|
||||||
provided by the ParsedCommand and ParsedTemplate APIs. The User-Facing construct is _Op Template_,
|
provided by the ParsedOp and ParsedTemplate APIs. The User-Facing construct is _Op Template_,
|
||||||
while the developer building driver adapters only sees _Parsed Commands_ and a fully-normalized API.
|
while the developer building driver adapters only sees _Parsed Commands_ and a fully-normalized API.
|
||||||
|
|
||||||
## Effective Op Mapping
|
## Effective Op Mapping
|
||||||
@ -74,9 +74,9 @@ constructor. Op Mappers may need access to the activity's parameters or the acti
|
|||||||
These can be provided from the DriverAdapter base type when needed.
|
These can be provided from the DriverAdapter base type when needed.
|
||||||
|
|
||||||
Assuming you provide the activity params and the space cache to an OpMapper implementation, when
|
Assuming you provide the activity params and the space cache to an OpMapper implementation, when
|
||||||
it's `apply(ParsedCommand cmd)` method is called, you have access to a few levels of information:
|
it's `apply(ParsedOp cmd)` method is called, you have access to a few levels of information:
|
||||||
|
|
||||||
1. The ParsedCommand -- representing the specific details of an operation to be performed:
|
1. The ParsedOp -- representing the specific details of an operation to be performed:
|
||||||
* op field names
|
* op field names
|
||||||
* static field values - literal values or any non-string collection type (map, set, list)
|
* static field values - literal values or any non-string collection type (map, set, list)
|
||||||
* dynamic field values - Any type which contains a string template or a single binding
|
* dynamic field values - Any type which contains a string template or a single binding
|
||||||
@ -142,12 +142,12 @@ Activites have configuration at various levels:
|
|||||||
5. op template fields
|
5. op template fields
|
||||||
|
|
||||||
Op template fields (seen by the NB driver developer through the
|
Op template fields (seen by the NB driver developer through the
|
||||||
ParsedCommand API) are properly meant to specify a distinct type of operation
|
ParsedOp API) are properly meant to specify a distinct type of operation
|
||||||
by its defined properties, no less or more. However, users will sometimes
|
by its defined properties, no less or more. However, users will sometimes
|
||||||
put op params into the op template alongside the op fields. This is *OK*.
|
put op params into the op template alongside the op fields. This is *OK*.
|
||||||
|
|
||||||
*The rule of thumb is to ensure that a named field can only be used as an
|
*The rule of thumb is to ensure that a named field can only be used as an
|
||||||
op field or an op param but not both.* Each ParsedCommand has access to
|
op field or an op param but not both.* Each ParsedOp has access to
|
||||||
all of the layers above, and should be used to extract out the fields
|
all of the layers above, and should be used to extract out the fields
|
||||||
which are properly configuration level data before the fields are used
|
which are properly configuration level data before the fields are used
|
||||||
for op mapping. By using this technique, op fields can be configured from any convenient
|
for op mapping. By using this technique, op fields can be configured from any convenient
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package io.nosqlbench.engine.api.templating;
|
|
||||||
|
|
||||||
import io.nosqlbench.engine.api.activityconfig.yaml.OpData;
|
|
||||||
import io.nosqlbench.nb.api.config.standard.ConfigModel;
|
|
||||||
import io.nosqlbench.nb.api.config.standard.Param;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.LongFunction;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
public class ParsedCommandTest {
|
|
||||||
|
|
||||||
ParsedCommand pc = new ParsedCommand(
|
|
||||||
new OpData().applyFields(
|
|
||||||
Map.of(
|
|
||||||
"op", Map.of(
|
|
||||||
"stmt", "test",
|
|
||||||
"dyna1", "{dyna1}",
|
|
||||||
"dyna2", "{{NumberNameToString()}}",
|
|
||||||
"identity", "{{Identity()}}"
|
|
||||||
),
|
|
||||||
"bindings", Map.of(
|
|
||||||
"dyna1", "NumberNameToString()"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
ConfigModel.of(ParsedCommandTest.class)
|
|
||||||
.add(Param.defaultTo("testcfg","testval"))
|
|
||||||
.asReadOnly()
|
|
||||||
.apply(Map.of())
|
|
||||||
);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParsedCommand() {
|
|
||||||
Map<String, Object> m1 = pc.apply(0);
|
|
||||||
assertThat(m1).containsEntry("stmt", "test");
|
|
||||||
assertThat(m1).containsEntry("dyna1","zero");
|
|
||||||
assertThat(m1).containsEntry("dyna2","zero");
|
|
||||||
assertThat(m1).containsEntry("identity", 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNewListBinder() {
|
|
||||||
LongFunction<List<Object>> lb = pc.newListBinder("dyna1", "identity", "dyna2", "identity");
|
|
||||||
List<Object> objects = lb.apply(1);
|
|
||||||
assertThat(objects).isEqualTo(List.of("one",1L,"one",1L));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNewMapBinder() {
|
|
||||||
LongFunction<Map<String, Object>> mb = pc.newOrderedMapBinder("dyna1", "identity", "dyna2");
|
|
||||||
Map<String, Object> objects = mb.apply(2);
|
|
||||||
assertThat(objects).isEqualTo(Map.<String,Object>of("dyna1","two","identity",2L,"dyna2","two"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNewAryBinder() {
|
|
||||||
LongFunction<Object[]> ab = pc.newArrayBinder("dyna1", "dyna1", "identity", "identity");
|
|
||||||
Object[] objects = ab.apply(3);
|
|
||||||
assertThat(objects).isEqualTo(new Object[]{"three","three",3L,3L});
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,7 @@ import io.nosqlbench.engine.api.activityimpl.input.ProgressCapable;
|
|||||||
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
||||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||||
import io.nosqlbench.engine.api.templating.CommandTemplate;
|
import io.nosqlbench.engine.api.templating.CommandTemplate;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.engine.api.templating.StrInterpolator;
|
import io.nosqlbench.engine.api.templating.StrInterpolator;
|
||||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
||||||
import io.nosqlbench.nb.api.errors.BasicError;
|
import io.nosqlbench.nb.api.errors.BasicError;
|
||||||
@ -427,11 +427,11 @@ public class SimpleActivity implements Activity, ProgressCapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected <O extends Op> OpSequence<OpDispenser<O>> createOpSourceFromCommands(
|
protected <O extends Op> OpSequence<OpDispenser<O>> createOpSourceFromCommands(
|
||||||
Function<ParsedCommand, OpDispenser<O>> opinit,
|
Function<ParsedOp, OpDispenser<O>> opinit,
|
||||||
NBConfiguration cfg,
|
NBConfiguration cfg,
|
||||||
List<Function<Map<String, Object>, Map<String, Object>>> parsers
|
List<Function<Map<String, Object>, Map<String, Object>>> parsers
|
||||||
) {
|
) {
|
||||||
Function<OpTemplate, ParsedCommand> f = t -> new ParsedCommand(t, cfg, parsers);
|
Function<OpTemplate, ParsedOp> f = t -> new ParsedOp(t, cfg, parsers);
|
||||||
Function<OpTemplate, OpDispenser<O>> opTemplateOFunction = f.andThen(opinit);
|
Function<OpTemplate, OpDispenser<O>> opTemplateOFunction = f.andThen(opinit);
|
||||||
return createOpSequence(opTemplateOFunction);
|
return createOpSequence(opTemplateOFunction);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
|||||||
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
|
||||||
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
|
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
|
||||||
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedCommand;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
import io.nosqlbench.nb.api.errors.OpConfigError;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,7 +33,7 @@ public class StandardActivity<R extends Op,S> extends SimpleActivity {
|
|||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Function<ParsedCommand, OpDispenser<R>> opmapper = adapter.getOpMapper();
|
Function<ParsedOp, OpDispenser<R>> opmapper = adapter.getOpMapper();
|
||||||
Function<Map<String, Object>, Map<String, Object>> preprocessor = adapter.getPreprocessor();
|
Function<Map<String, Object>, Map<String, Object>> preprocessor = adapter.getPreprocessor();
|
||||||
sequence = createOpSourceFromCommands(opmapper, adapter.getConfiguration(), List.of(preprocessor));
|
sequence = createOpSourceFromCommands(opmapper, adapter.getConfiguration(), List.of(preprocessor));
|
||||||
opsource= OpSource.of(sequence);
|
opsource= OpSource.of(sequence);
|
||||||
|
Loading…
Reference in New Issue
Block a user