organize and improve cycles and recycles logic

This commit is contained in:
Jonathan Shook 2023-09-09 16:03:37 -05:00
parent 60e8d3d696
commit 3aab634522
2 changed files with 122 additions and 54 deletions

View File

@ -17,7 +17,6 @@
package io.nosqlbench.api.engine.activityimpl;
import io.nosqlbench.api.config.NBNamedElement;
import io.nosqlbench.api.engine.util.Unit;
import io.nosqlbench.api.errors.BasicError;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -40,23 +39,27 @@ public class ActivityDef implements NBNamedElement {
// milliseconds between cycles per thread, for slow tests only
public static final String DEFAULT_ALIAS = "UNNAMEDACTIVITY";
public static final String DEFAULT_ATYPE = "stdout ";
public static final String DEFAULT_ATYPE = "stdout";
public static final String DEFAULT_CYCLES = "0";
public static final String DEFAULT_RECYCLES = "1";
public static final int DEFAULT_THREADS = 1;
private static final Logger logger = LogManager.getLogger(ActivityDef.class);
public static final Logger logger = LogManager.getLogger(ActivityDef.class);
// an alias with which to control the activity while it is running
private static final String FIELD_ALIAS = "alias";
public static final String FIELD_ALIAS = "alias";
// a file or URL containing the activity: op templates, generator bindings, ...
private static final String FIELD_ATYPE = "type";
public static final String FIELD_ATYPE = "type";
// cycles for this activity in either "M" or "N..M" form. "M" form implies "0..M"
private static final String FIELD_CYCLES = "cycles";
public static final String FIELD_CYCLES = "cycles";
public static final String FIELD_RECYCLES = "recycles";
// initial thread concurrency for this activity
private static final String FIELD_THREADS = "threads";
private static final String[] field_list = {
FIELD_ALIAS, FIELD_ATYPE, FIELD_CYCLES, FIELD_THREADS
public static final String FIELD_THREADS = "threads";
public static final String[] field_list = {
FIELD_ALIAS, FIELD_ATYPE, FIELD_CYCLES, FIELD_THREADS, FIELD_RECYCLES
};
// parameter map has its own internal atomic map
private final ParameterMap parameterMap;
private CyclesSpec cyclesSpec;
private CyclesSpec reCyclesSpec;
public ActivityDef(ParameterMap parameterMap) {
this.parameterMap = parameterMap;
@ -107,34 +110,22 @@ public class ActivityDef implements NBNamedElement {
* @return the long start cycle
*/
public long getStartCycle() {
String cycles = parameterMap.getOptionalString("cycles").orElse(DEFAULT_CYCLES);
int rangeAt = cycles.indexOf("..");
String startCycle;
if (0 < rangeAt) {
startCycle = cycles.substring(0, rangeAt);
} else {
startCycle = "0";
}
return Unit.longCountFor(startCycle).orElseThrow(
() -> new RuntimeException("Unable to parse start cycles from " + startCycle)
);
return getCyclesSpec().first_inclusive();
}
public void setStartCycle(long startCycle) {
parameterMap.set(FIELD_CYCLES, startCycle + ".." + getEndCycle());
public void setStartCycle(long firstCycleInclusive) {
cyclesSpec=getCyclesSpec().withFirst(firstCycleInclusive);
}
public void setStartCycle(String startCycle) {
setStartCycle(Unit.longCountFor(startCycle).orElseThrow(
() -> new RuntimeException("Unable to convert start cycle '" + startCycle + "' to a value.")
));
public void setStartCycle(String firstCycleInclusive) {
cyclesSpec=getCyclesSpec().withFirst(firstCycleInclusive);
}
public void setEndCycle(String endCycle) {
setEndCycle(Unit.longCountFor(endCycle).orElseThrow(
() -> new RuntimeException("Unable to convert end cycle '" + endCycle + "' to a value.")
));
public void setEndCycle(long lastCycleExclusive) {
cyclesSpec=getCyclesSpec().withLast(lastCycleExclusive);
}
public void setEndCycle(String lastCycleExclusive) {
cyclesSpec=getCyclesSpec().withLast(lastCycleExclusive);
}
/**
@ -143,21 +134,7 @@ public class ActivityDef implements NBNamedElement {
* @return the long end cycle
*/
public long getEndCycle() {
String cycles = parameterMap.getOptionalString(FIELD_CYCLES).orElse(DEFAULT_CYCLES);
int rangeAt = cycles.indexOf("..");
String endCycle;
if (0 < rangeAt) {
endCycle = cycles.substring(rangeAt + 2);
} else {
endCycle = cycles;
}
return Unit.longCountFor(endCycle).orElseThrow(
() -> new RuntimeException("Unable to convert end cycle from " + endCycle)
);
}
public void setEndCycle(long endCycle) {
parameterMap.set(FIELD_CYCLES, getStartCycle() + ".." + endCycle);
return getCyclesSpec().last_exclusive();
}
/**
@ -188,22 +165,33 @@ public class ActivityDef implements NBNamedElement {
public void setCycles(String cycles) {
parameterMap.set(FIELD_CYCLES, cycles);
this.cyclesSpec=CyclesSpec.parse(cycles);
checkInvariants();
}
public String getCycleSummary() {
return "["
+ getStartCycle()
+ ".."
+ getEndCycle()
+ ")="
+ getCycleCount();
return getCyclesSpec().summary();
}
public long getCycleCount() {
return getEndCycle() - getStartCycle();
public synchronized long getCycleCount() {
return getCyclesSpec().cycle_count();
}
public synchronized CyclesSpec getCyclesSpec() {
if (this.cyclesSpec==null) {
this.cyclesSpec = CyclesSpec.parse(parameterMap.getOptionalString(FIELD_CYCLES).orElse(DEFAULT_CYCLES));
}
return this.cyclesSpec;
}
public synchronized CyclesSpec getRecyclesSpec() {
if (this.reCyclesSpec==null) {
this.reCyclesSpec = CyclesSpec.parse(parameterMap.getOptionalString(FIELD_RECYCLES).orElse(DEFAULT_RECYCLES));
}
return this.reCyclesSpec;
}
private void checkInvariants() {
if (getStartCycle() >= getEndCycle()) {
throw new InvalidParameterException("Start cycle must be strictly less than end cycle, but they are [" + getStartCycle() + ',' + getEndCycle() + ')');

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2023 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.
*/
package io.nosqlbench.api.engine.activityimpl;
import io.nosqlbench.api.engine.util.Unit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.security.InvalidParameterException;
public record CyclesSpec(long first_inclusive, long last_exclusive, String firstSpec, String lastSpec) {
private final static Logger logger = LogManager.getLogger(CyclesSpec.class);
public CyclesSpec {
if (first_inclusive>last_exclusive) {
throw new InvalidParameterException("cycles must start with a lower first cycle than last cycle");
}
if (first_inclusive==last_exclusive) {
logger.warn("This cycles interval means zero total:" + this);
}
}
public static CyclesSpec parse(String spec) {
int rangeAt = spec.indexOf("..");
String beginningInclusive = "0";
String endingExclusive = spec;
if (0 < rangeAt) {
beginningInclusive = spec.substring(0, rangeAt);
endingExclusive = spec.substring(rangeAt+2);
}
long first = Unit.longCountFor(beginningInclusive).orElseThrow(() -> new RuntimeException("Unable to parse start cycles from " + spec));
long last = Unit.longCountFor(endingExclusive).orElseThrow(() -> new RuntimeException("Unable to parse start cycles from " + spec));
return new CyclesSpec(first, last, beginningInclusive, endingExclusive);
}
public String summary() {
return "[" + firstSpec + ".." + lastSpec + ")=" + (last_exclusive - first_inclusive);
}
@Override
public String toString() {
return firstSpec + ".." + lastSpec;
}
public CyclesSpec withFirst(long first) {
return new CyclesSpec(first, last_exclusive, String.valueOf(first), lastSpec);
}
public CyclesSpec withFirst(String firstSpec) {
long start = Unit.longCountFor(firstSpec).orElseThrow(() -> new RuntimeException("Unable to parse start cycle from " + firstSpec));
return new CyclesSpec(start, last_exclusive, firstSpec, lastSpec);
}
public CyclesSpec withLast(long last) {
return new CyclesSpec(first_inclusive, last, firstSpec, String.valueOf(last));
}
public CyclesSpec withLast(String lastSpec) {
long last = Unit.longCountFor(lastSpec).orElseThrow(() -> new RuntimeException("Unable to parse end cycle from " + lastSpec));
return new CyclesSpec(first_inclusive, last, firstSpec, lastSpec);
}
public long cycle_count() {
return last_exclusive -first_inclusive;
}
}