mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
temp checkpoint
This commit is contained in:
@@ -105,7 +105,6 @@ public class OpDef extends OpTemplate {
|
||||
private LinkedHashMap<String, String> composeTags() {
|
||||
LinkedHashMap<String, String> tagsWithName = new LinkedHashMap<>(new MultiMapLookup<>(rawOpDef.getTags(), block.getTags()));
|
||||
tagsWithName.put("block",block.getName());
|
||||
tagsWithName.put("name",this.rawOpDef.getName());
|
||||
tagsWithName.put("op",this.rawOpDef.getName());
|
||||
return tagsWithName;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package io.nosqlbench.adapters.api.activityimpl;
|
||||
import com.codahale.metrics.Timer;
|
||||
import groovy.lang.Binding;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.Space;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.Validator;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.ValidatorSource;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.CycleOp;
|
||||
import io.nosqlbench.adapters.api.evalctx.*;
|
||||
import io.nosqlbench.adapters.api.metrics.ThreadLocalNamedTimers;
|
||||
@@ -35,6 +37,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
@@ -48,7 +51,9 @@ import java.util.function.LongFunction;
|
||||
* The type of operation
|
||||
*/
|
||||
public abstract class BaseOpDispenser<OP extends CycleOp<?>, SPACE extends Space>
|
||||
extends NBBaseComponent implements OpDispenser<OP> {
|
||||
extends NBBaseComponent
|
||||
implements OpDispenser<OP>, ValidatorSource
|
||||
{
|
||||
protected final static Logger logger = LogManager.getLogger(BaseOpDispenser.class);
|
||||
public static final String VERIFIER = "verifier";
|
||||
public static final String VERIFIER_INIT = "verifier-init";
|
||||
@@ -230,4 +235,9 @@ public abstract class BaseOpDispenser<OP extends CycleOp<?>, SPACE extends Space
|
||||
OP op = getOp(value);
|
||||
return op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Validator> getValidator(NBComponent parent, ParsedOp pop, OpLookup lookup) {
|
||||
return CoreOpValidators.getValidator(this, pop, lookup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package io.nosqlbench.adapters.api.activityimpl;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.Validator;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import io.nosqlbench.engine.api.templating.TypeAndTarget;
|
||||
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CoreOpValidators {
|
||||
private static final Logger logger = LogManager.getLogger(CoreOpValidators.class);
|
||||
|
||||
public static List<Validator> getValidator(NBComponent parent, ParsedOp pop, OpLookup lookup) {
|
||||
List<Validator> validators = new ArrayList();
|
||||
Optional<TypeAndTarget<CoreValidators, Object>> optionalValidator = pop.getOptionalTypeAndTargetEnum(
|
||||
CoreValidators.class, Object.class);
|
||||
|
||||
if (optionalValidator.isPresent()) {
|
||||
TypeAndTarget<CoreValidators, Object> validator = optionalValidator.get();
|
||||
logger.debug("found validator '" + validator.enumId.name() + "' for op '" + pop.getName() + "'");
|
||||
switch (validator.enumId) {
|
||||
case verify_fields:
|
||||
validators.add(new FieldVerifier(parent, pop, lookup));
|
||||
}
|
||||
}
|
||||
|
||||
return validators;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.nosqlbench.adapters.api.activityimpl;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.Validator;
|
||||
|
||||
public enum CoreValidators {
|
||||
verify_fields(FieldVerifier.class);
|
||||
private final Class<? extends Validator> validatorImpl;
|
||||
|
||||
CoreValidators(Class<? extends Validator> validatorClass) {
|
||||
this.validatorImpl = validatorClass;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package io.nosqlbench.adapters.api.activityimpl;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.Validator;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.opwrappers.DiffType;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
|
||||
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricCounter;
|
||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
||||
import io.nosqlbench.virtdata.core.templates.BindPoint;
|
||||
import io.nosqlbench.virtdata.core.templates.CapturePoints;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// TODO: Make op(verifyref) use tags, and require 1
|
||||
public class FieldVerifier implements Validator {
|
||||
|
||||
private final LongFunction<Map<String, Object>> expectedValuesF;
|
||||
private final DiffType diffType;
|
||||
private final NBMetricCounter resultsVerifiedError;
|
||||
private final NBMetricCounter resultsOkCounter;
|
||||
private final NBMetricCounter verifiedFieldsCounter;
|
||||
private final String[] fieldNames;
|
||||
private final String[] bindingNames;
|
||||
|
||||
public FieldVerifier(NBComponent parent, ParsedOp pop, OpLookup lookup) {
|
||||
this.resultsVerifiedError = parent.create().counter(
|
||||
"results_verified_error", MetricCategory.Verification,
|
||||
"The number of results which have been verified with no error"
|
||||
);
|
||||
this.resultsOkCounter = parent.create().counter(
|
||||
"results_verified_ok",
|
||||
MetricCategory.Verification,
|
||||
"The number of results which had " + "a verification error"
|
||||
);
|
||||
this.verifiedFieldsCounter = parent.create().counter(
|
||||
"field_verified_ok", MetricCategory.Verification,
|
||||
"the number of fields in results which have been verified with no error"
|
||||
);
|
||||
|
||||
this.diffType = pop.takeEnumFromFieldOr(DiffType.class, DiffType.all, "compare");
|
||||
|
||||
List<String> fields = new ArrayList<>();
|
||||
List<String> bindings = new ArrayList<>();
|
||||
CapturePoints captures = pop.getCaptures();
|
||||
|
||||
ParsedOp config = pop.takeAsSubConfig("verify_fields");
|
||||
|
||||
Optional<Object> vspec = config.takeOptionalStaticValue("verify_fields", Object.class);
|
||||
if (vspec.isPresent()) {
|
||||
Object vspeco = vspec.get();
|
||||
if (vspeco instanceof Map verifyers) {
|
||||
verifyers.forEach((k, v) -> {
|
||||
if (k instanceof CharSequence keyName && v instanceof CharSequence keyValue) {
|
||||
fields.add(keyName.toString());
|
||||
bindings.add(keyValue.toString());
|
||||
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"Strings must be used in map form of " + "verify_field");
|
||||
}
|
||||
|
||||
});
|
||||
} else if (vspeco instanceof String verifyBindingSpec) {
|
||||
parseFieldSpec(verifyBindingSpec, lookup, fields, bindings, captures, pop);
|
||||
} else {
|
||||
throw new OpConfigError("Unrecognized type for verify_fields value:" + vspeco.getClass().getSimpleName());
|
||||
}
|
||||
} else {
|
||||
config.getDefinedNames().forEach(name -> {
|
||||
fields.add(name);
|
||||
bindings.add(config.getStaticValue(name));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
List<BindPoint> bindPoints = pop.getBindPoints();
|
||||
|
||||
// Optional<String> vb = config.getOptionalStaticValue("verify_bindings", String.class);
|
||||
// if (vb.isPresent()) {
|
||||
// String verifyBindingSpec = vb.get();
|
||||
// if (verifyBindingSpec.startsWith("op(") && verifyBindingSpec.endsWith(")")) {
|
||||
// String toLookup = verifyBindingSpec.substring(2, verifyBindingSpec.lastIndexOf(-1));
|
||||
// ParsedOp referenced = lookup.lookup(toLookup).orElseThrow();
|
||||
// }
|
||||
// }
|
||||
|
||||
this.fieldNames = fields.toArray(new String[fields.size()]);
|
||||
this.bindingNames = bindings.toArray(new String[bindings.size()]);
|
||||
this.expectedValuesF = pop.newOrderedMapBinder(bindingNames);
|
||||
|
||||
}
|
||||
|
||||
private void parseFieldSpec(
|
||||
String fieldSpec, OpLookup lookup, List<String> fields,
|
||||
List<String> bindings, CapturePoints captures, ParsedOp pop
|
||||
) {
|
||||
if (fieldSpec.startsWith("op(") && fieldSpec.endsWith(")")) {
|
||||
String toLookup = fieldSpec.substring("op(".length(), fieldSpec.length() - 1);
|
||||
Optional<ParsedOp> referenced = lookup.lookup(toLookup);
|
||||
if (referenced.isPresent()) {
|
||||
List<String> vars = referenced.get().getBindPoints().stream().map(
|
||||
bp -> bp.getAnchor()).toList();
|
||||
fields.addAll(vars);
|
||||
bindings.addAll(vars);
|
||||
} else {
|
||||
throw new OpConfigError(
|
||||
"no op found for verify setting '" + fieldSpec + "' " + "for op " + "template" + " '" + pop.getName() + "'");
|
||||
}
|
||||
} else {
|
||||
String[] vfields = fieldSpec.split("\\s*,\\s*");
|
||||
for (String vfield : vfields) {
|
||||
// if (vfield.equals("*")) {
|
||||
// fields.addAll(captures.getAsNames());
|
||||
// fields.addAll(bindPoints.stream().map(bp -> bp.getAnchor()).toList());
|
||||
// } else
|
||||
if (vfield.startsWith("+")) {
|
||||
fields.add(vfield.substring(1));
|
||||
} else if (vfield.startsWith("-")) {
|
||||
fields.remove(vfield.substring(1));
|
||||
} else if (vfield.matches("\\w+(\\w+->[\\w-]+)?")) {
|
||||
String[] parts = vfield.split("->", 2);
|
||||
fields.add(parts[0]);
|
||||
bindings.add(parts[1]);
|
||||
} else {
|
||||
throw new RuntimeException("unknown verify_fields format: '" + vfield + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Compare the values of the row with the values generated.
|
||||
///
|
||||
/// Specifically,
|
||||
/// - Ensure the same number of fields.
|
||||
/// - Ensure the same pair-wise field names.
|
||||
/// - Ensure that each pair of same-named fields has the same data type.
|
||||
/// - Ensure that the value of each pair of fields is equal according to the equals
|
||||
/// operator for the respective type.
|
||||
/// @return a count of differences between the row and the reference values
|
||||
@Override
|
||||
public void validate(long cycle, Object data) {
|
||||
if (data instanceof Map<?, ?> r) {
|
||||
Map<String, ?> result = (Map<String, ?>) r;
|
||||
Map<String, Object> referenceMap = this.expectedValuesF.apply(cycle);
|
||||
|
||||
int diff = 0;
|
||||
StringBuilder logbuffer = new StringBuilder(); // make this a TL
|
||||
logbuffer.setLength(0);
|
||||
|
||||
if (diffType.is(DiffType.reffields)) {
|
||||
|
||||
List<String> missingRowFields = Arrays.stream(this.fieldNames).filter(
|
||||
gk -> !result.containsKey(gk)).collect(Collectors.toList());
|
||||
if (missingRowFields.size() > 0) {
|
||||
diff += missingRowFields.size();
|
||||
|
||||
logbuffer.append("\nexpected fields '");
|
||||
logbuffer.append(String.join("','", missingRowFields));
|
||||
logbuffer.append("' not in row.");
|
||||
}
|
||||
}
|
||||
|
||||
// if (diffType.is(DiffType.rowfields)) {
|
||||
// List<String> missingRefFields = result.keySet().stream().filter(
|
||||
// k -> !referenceMap.containsKey(k)).collect(Collectors.toList());
|
||||
// if (missingRefFields.size() > 0) {
|
||||
// diff += missingRefFields.size();
|
||||
//
|
||||
// logbuffer.append("\nexpected fields '");
|
||||
// logbuffer.append(String.join("','", missingRefFields));
|
||||
// logbuffer.append("' not in reference data: " + referenceMap);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (diffType.is(DiffType.values)) {
|
||||
for (int fidx = 0; fidx < fieldNames.length; fidx++) {
|
||||
String fname = fieldNames[fidx];
|
||||
;
|
||||
String rname = bindingNames[fidx];
|
||||
if (referenceMap.containsKey(rname)) {
|
||||
if (referenceMap.get(rname).equals(result.get(fname))) {
|
||||
verifiedFieldsCounter.inc();
|
||||
} else {
|
||||
logbuffer.append("\nvalue differs for '").append(fname).append("' ");
|
||||
logbuffer.append("expected:'").append(
|
||||
referenceMap.get(fname).toString()).append("'");
|
||||
logbuffer.append(" actual:'").append(result.get(rname)).append("'");
|
||||
diff++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (diff == 0) {
|
||||
resultsVerifiedError.inc();
|
||||
} else {
|
||||
resultsOkCounter.inc();
|
||||
throw new RuntimeException("in cycle " + cycle + ", " + logbuffer.toString());
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new OpConfigError("Can only validate fields of type Map");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "verify_fields";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.nosqlbench.adapters.api.activityimpl;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface OpLookup {
|
||||
Optional<ParsedOp> lookup(String opName);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.nosqlbench.adapters.api.activityimpl.uniform;
|
||||
|
||||
import java.util.Map;
|
||||
import io.nosqlbench.adapters.api.activityimpl.OpDispenser;
|
||||
import io.nosqlbench.nb.api.components.core.NBNamedElement;
|
||||
import io.nosqlbench.virtdata.core.templates.BindPoint;
|
||||
|
||||
/// This optional type allows for [OpDispenser] (or other) implementations to
|
||||
/// map native field names to their associated binding names. Often, the
|
||||
/// adapter-native logic is the only place this association can be derived, although
|
||||
/// it is sometimes needed in core adapter-agnostic logic.
|
||||
public interface FieldBindingsMetadata<FIELDTYPE> {
|
||||
|
||||
/// Get the map of native fields to bind points.
|
||||
/// The bind points don't need to be the same actual object which is used, but both the
|
||||
/// field names and the binding points should be equivalent as in [Object#equals].
|
||||
/// @return an ordered map of native driver/client fields to their associated bindpoints.
|
||||
Map<String, BindPoint> getFieldBindingsMap();
|
||||
|
||||
}
|
||||
@@ -2,13 +2,13 @@ package io.nosqlbench.adapters.api.activityimpl.uniform;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@@ -18,6 +18,8 @@ package io.nosqlbench.adapters.api.activityimpl.uniform;
|
||||
*/
|
||||
|
||||
|
||||
public interface Validator<RESULT> {
|
||||
public void validate(RESULT result);
|
||||
import io.nosqlbench.nb.api.components.core.NBNamedElement;
|
||||
|
||||
public interface Validator<RESULT> extends NBNamedElement {
|
||||
public void validate(long cycle, RESULT result);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package io.nosqlbench.adapters.api.activityimpl.uniform;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@@ -18,12 +18,15 @@ package io.nosqlbench.adapters.api.activityimpl.uniform;
|
||||
*/
|
||||
|
||||
|
||||
import io.nosqlbench.adapters.api.activityimpl.OpLookup;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/// A [DriverAdapter] may implement this interface to provide adapter-specific
|
||||
/// validators.
|
||||
public interface ValidatorSource {
|
||||
Optional<Validator> getValidator(String name, ParsedOp pop);
|
||||
List<Validator> getValidator(NBComponent parent, ParsedOp pop, OpLookup lookup);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class AssertingOp<T> implements CycleOp<T> {
|
||||
@Override
|
||||
public T apply(long value) {
|
||||
T result = op.apply(value);
|
||||
validator.validate(result);
|
||||
validator.validate(value, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package io.nosqlbench.adapters.api.activityimpl.uniform.opwrappers;
|
||||
|
||||
/*
|
||||
* Copyright (c) nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
public enum DiffType {
|
||||
|
||||
|
||||
/// Verify nothing for this statement
|
||||
none(0),
|
||||
|
||||
/// Verify that fields named in the row are present in the reference map.
|
||||
rowfields(0x1),
|
||||
|
||||
/// Verify that fields in the reference map are present in the row data.
|
||||
reffields(0x1 << 1),
|
||||
|
||||
/// Verify that all fields present in either the row or the reference data
|
||||
/// are also present in the other.
|
||||
fields(0x1 | 0x1 << 1),
|
||||
|
||||
/// Verify that all values of the same named field are equal, according to
|
||||
/// {@link Object#equals(Object)}}.
|
||||
values(0x1<<2),
|
||||
|
||||
/// Cross-verify all fields and field values between the reference data and
|
||||
/// the actual data.
|
||||
all(0x1|0x1<<1|0x1<<2);
|
||||
|
||||
public int bitmask;
|
||||
|
||||
DiffType(int bit) {
|
||||
this.bitmask = bit;
|
||||
}
|
||||
|
||||
public boolean is(DiffType option) {
|
||||
return (bitmask & option.bitmask) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import io.nosqlbench.nb.api.config.fieldreaders.DynamicFieldReader;
|
||||
import io.nosqlbench.nb.api.config.fieldreaders.StaticFieldReader;
|
||||
import io.nosqlbench.nb.api.config.standard.NBConfigError;
|
||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
||||
import io.nosqlbench.nb.api.engine.util.Tagged;
|
||||
import io.nosqlbench.nb.api.errors.OpConfigError;
|
||||
import io.nosqlbench.nb.api.labels.NBLabelSpec;
|
||||
import io.nosqlbench.nb.api.labels.NBLabels;
|
||||
@@ -380,7 +381,7 @@ prepared: false
|
||||
field within the set of possible fields. More than one will throw an error.</LI>
|
||||
</UL>
|
||||
</P> */
|
||||
public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String, ?>>, NBComponent, StaticFieldReader, DynamicFieldReader {
|
||||
public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String, ?>>, NBComponent, StaticFieldReader, DynamicFieldReader, Tagged {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(ParsedOp.class);
|
||||
|
||||
@@ -418,9 +419,12 @@ public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String
|
||||
List<Function<Map<String, Object>, Map<String, Object>>> preprocessors,
|
||||
NBComponent parent
|
||||
) {
|
||||
// TODO: the block and op name below should be populated more robustly
|
||||
// They should not be strictly required, but a way of taking "what is provided" in the
|
||||
// name should be used
|
||||
super(
|
||||
parent,
|
||||
NBLabels.forKV(((parent instanceof ParsedOp) ? "subop" : "op"), opTemplate.getName())
|
||||
NBLabels.forMap(opTemplate.getTags())
|
||||
);
|
||||
this._opTemplate = opTemplate;
|
||||
this.activityCfg = activityCfg;
|
||||
@@ -894,6 +898,7 @@ public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String
|
||||
return tmap.getOptionalTargetEnum(enumclass, valueClass);
|
||||
}
|
||||
|
||||
|
||||
public <E extends Enum<E>, V> Optional<TypeAndTarget<E, V>> getOptionalTypeAndTargetEnum(
|
||||
Class<E> enumclass, Class<V> valueClass) {
|
||||
return tmap.getOptionalTargetEnum(enumclass, valueClass);
|
||||
@@ -1025,6 +1030,11 @@ public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String
|
||||
return this._opTemplate.getRefKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getTags() {
|
||||
return this._opTemplate.getTags();
|
||||
}
|
||||
|
||||
|
||||
public static enum SubOpNaming {
|
||||
SubKey, ParentAndSubKey
|
||||
@@ -1046,9 +1056,9 @@ public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String
|
||||
return new ParsedOp(
|
||||
new OpData(
|
||||
"sub-op of '" + this.getName() + "' field '" + fromOpField + "', element '" + elemName + "' name '" + subopName + "'",
|
||||
subopName, new LinkedHashMap<String, String>(_opTemplate.getTags()) {{
|
||||
put("subop", subopName);
|
||||
}}, _opTemplate.getBindings(), _opTemplate.getParams(), opfields, 100
|
||||
subopName,
|
||||
new LinkedHashMap<String, String>(Map.of("subop", subopName)),
|
||||
_opTemplate.getBindings(), _opTemplate.getParams(), opfields, 100
|
||||
), this.activityCfg, List.of(), this
|
||||
);
|
||||
}
|
||||
@@ -1096,10 +1106,23 @@ public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String
|
||||
return subOpMap;
|
||||
}
|
||||
|
||||
public ParsedOp takeAsSubConfig(String s) {
|
||||
Object subtree = tmap.takeStaticValue(s, Object.class);
|
||||
if (subtree instanceof Map map) {
|
||||
return makeSubOp(s, s, map, SubOpNaming.SubKey);
|
||||
} else if (subtree instanceof String seq) {
|
||||
return makeSubOp(s, s, Map.of(s, seq), SubOpNaming.SubKey);
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"unable to make sub config from key '" + s + "', because " + "it is a " + subtree.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public ParsedOp getAsSubOp(String name, SubOpNaming naming) {
|
||||
Object o = _opTemplate.getOp().map(raw -> raw.get(name)).orElseThrow(
|
||||
() -> new OpConfigError(
|
||||
"Could not find op field '" + name + "' for subop on parent op '" + name + "'"));
|
||||
|
||||
if (o instanceof Map map) {
|
||||
return makeSubOp(this.getName(), name, map, naming);
|
||||
} else {
|
||||
@@ -1230,8 +1253,8 @@ public class ParsedOp extends NBBaseComponent implements LongFunction<Map<String
|
||||
return tmap.getCaptures();
|
||||
}
|
||||
|
||||
public Map<String, String> getBindPoints() {
|
||||
return null;
|
||||
public List<BindPoint> getBindPoints() {
|
||||
return tmap.getBindPoints();
|
||||
}
|
||||
|
||||
public boolean isDefinedExactly(String... fields) {
|
||||
|
||||
Reference in New Issue
Block a user