diff --git a/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/RateLimiters.java b/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/RateLimiters.java
index 582f890f0..676a873e6 100644
--- a/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/RateLimiters.java
+++ b/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/RateLimiters.java
@@ -25,13 +25,9 @@ public enum RateLimiters {
private static final Logger logger = LogManager.getLogger(RateLimiters.class);
public static synchronized RateLimiter createOrUpdate(final NBComponent parent, final RateLimiter extant, final SimRateSpec spec) {
- return createOrUpdate(parent, extant, spec, "cycle");
- }
-
- public static synchronized RateLimiter createOrUpdate(final NBComponent parent, final RateLimiter extant, final SimRateSpec spec,final String type) {
if (null == extant) {
- final RateLimiter rateLimiter= new SimRate(parent, spec, type);
+ final RateLimiter rateLimiter= new SimRate(parent, spec);
RateLimiters.logger.info(() -> "Using rate limiter: " + rateLimiter);
return rateLimiter;
diff --git a/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/SimRate.java b/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/SimRate.java
index f2e48122a..e2848b3fc 100644
--- a/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/SimRate.java
+++ b/engine-core/src/main/java/io/nosqlbench/engine/api/activityapi/simrate/SimRate.java
@@ -79,58 +79,34 @@ public class SimRate extends NBBaseComponent implements RateLimiter, Thread.Unca
private long startTime;
public SimRate(NBComponent parent, SimRateSpec spec) {
- this(parent, spec, "cycle");
- }
-
- public SimRate(NBComponent parent, SimRateSpec spec, String type) {
- super(parent, NBLabels.forKV());
+ super(parent, NBLabels.forKV().and("rateType",
+ (spec instanceof CycleRateSpec? "cycle" : "stride")));
this.spec = spec;
- initMetrics(type);
+ initMetrics();
startFiller();
}
- private void initMetrics(String type) {
- if (type.equalsIgnoreCase("cycle")) {
- create().gauge(
- "cycles_waittime",
- () -> (double) getWaitTimeDuration().get(ChronoUnit.NANOS),
- MetricCategory.Core,
- "The cumulative scheduling delay which accrues when" +
- " an activity is not able to execute operations as fast as requested."
- );
- create().gauge(
- "config_cyclerate",
- () -> spec.opsPerSec,
- MetricCategory.Config,
- "The configured cycle rate in ops/s"
- );
- create().gauge(
- "config_burstrate",
- () -> spec.burstRatio,
- MetricCategory.Config,
- "the configured burst rate as a multiplier to the configured cycle rate. ex: 1.05 means 5% faster is allowed."
- );
- } else {
- create().gauge(
- "stride_waittime",
- () -> (double) getWaitTimeDuration().get(ChronoUnit.NANOS),
- MetricCategory.Core,
- "The cumulative scheduling delay which accrues when" +
- " an activity is not able to execute operations as fast as requested."
- );
- create().gauge(
- "config_striderate",
- () -> spec.opsPerSec,
- MetricCategory.Config,
- "The configured stride rate in ops/s"
- );
- create().gauge(
- "config_burstrate",
- () -> spec.burstRatio,
- MetricCategory.Config,
- "the configured burst rate as a multiplier to the configured cycle rate. ex: 1.05 means 5% faster is allowed."
- );
- }
+ private void initMetrics() {
+ String rateType = getLabels().valueOf("rateType");
+ create().gauge(
+ rateType + "s_waittime",
+ () -> (double) getWaitTimeDuration().get(ChronoUnit.NANOS),
+ MetricCategory.Core,
+ "The cumulative scheduling delay which accrues when" +
+ " an activity is not able to execute operations as fast as requested."
+ );
+ create().gauge(
+ "config_" + rateType + "rate",
+ () -> spec.opsPerSec,
+ MetricCategory.Config,
+ "The configured cycle rate in ops/s"
+ );
+ create().gauge(
+ rateType + "_config_burstrate",
+ () -> spec.burstRatio,
+ MetricCategory.Config,
+ "the configured burst rate as a multiplier to the configured cycle rate. ex: 1.05 means 5% faster is allowed."
+ );
}
public long refill() {
diff --git a/engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java b/engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java
index 44da12c1f..e391b3753 100644
--- a/engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java
+++ b/engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java
@@ -89,8 +89,6 @@ public class SimpleActivity extends NBStatusComponent implements Activity, Invok
private ActivityMetricProgressMeter progressMeter;
private String workloadSource = "unspecified";
private final RunStateTally tally = new RunStateTally();
- public static final String STRIDE = "stride";
- public static final String CYCLE = "cycle";
public SimpleActivity(NBComponent parent, ActivityDef activityDef) {
super(parent, NBLabels.forKV("activity", activityDef.getAlias()).and(activityDef.auxLabels()));
@@ -317,11 +315,11 @@ public class SimpleActivity extends NBStatusComponent implements Activity, Invok
}
public void createOrUpdateStrideLimiter(SimRateSpec spec) {
- strideLimiter = RateLimiters.createOrUpdate(this, strideLimiter, spec, STRIDE);
+ strideLimiter = RateLimiters.createOrUpdate(this, strideLimiter, spec);
}
public void createOrUpdateCycleLimiter(SimRateSpec spec) {
- cycleLimiter = RateLimiters.createOrUpdate(this, cycleLimiter, spec, CYCLE);
+ cycleLimiter = RateLimiters.createOrUpdate(this, cycleLimiter, spec);
}
/**
diff --git a/virtdata-api/src/main/java/io/nosqlbench/virtdata/api/bindings/VirtDataConversions.java b/virtdata-api/src/main/java/io/nosqlbench/virtdata/api/bindings/VirtDataConversions.java
index 189575829..d04005194 100644
--- a/virtdata-api/src/main/java/io/nosqlbench/virtdata/api/bindings/VirtDataConversions.java
+++ b/virtdata-api/src/main/java/io/nosqlbench/virtdata/api/bindings/VirtDataConversions.java
@@ -20,10 +20,7 @@ import io.nosqlbench.nb.api.errors.BasicError;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.TypeVariable;
+import java.lang.reflect.*;
import java.security.InvalidParameterException;
import java.util.*;
import java.util.function.LongFunction;
@@ -70,6 +67,18 @@ public class VirtDataConversions {
private static final Logger logger = LogManager.getLogger(VirtDataConversions.class);
+ public static
+ *
This implementation is available for specialized use when needed, but the + * above versions are much more self-explanatory and easy to use.
+ * + *As with previous implementations, the basic input which is fed to the functions + * is the sum of the input cycle and the step, where the step is simply the index of + * the insertion point within the template string. These start at 0, so a template string + * which contains "{}-{}" will have two steps, 0, and 1. For cycle 35, the first + * function will take input 35, and the second 36. This can create some local neighborhood + * similarity in test data, so other forms are provided which can hash the values for + * an added degree of (effective) randomness and one that chains these so that each + * set of values from a Concat binding are quite distinct from each other.
+ *+ *
Binding functions used to populate each step of the template may have their own bounds + * of output values like {@link Combinations}. These are easy to use internally since they + * work well with the hashing. However, some other functions may operate over the whole space + * of long values, and come with no built-in cardinality constraints. It is recommended to + * use those with built-in constraints when you want to render a discrete population of values.
+ */ +@ThreadSafeMapper +@Categories(Category.general) +public class Concat implements LongFunctionThis is a variant of Concat which chains the hash values + * from step to step so that each of the provided functions will + * yield unrelated values. The first input value to a function + * is a hash of the cycle input value, the next is a hash of the + * first input value, and so on.
+ */ +@ThreadSafeMapper +@Categories(Category.general) +public class ConcatChained extends Concat { + private final static Hash hash = new Hash(); + public ConcatChained(String template, Object... functions) { + super((c,s) -> hash.applyAsLong(c+s), template, functions); + } + + @Override + public String apply(long cycle) { + StringBuilder buffer = new StringBuilder(); + buffer.setLength(0); + buffer.append(literals[0]); + long value = cycle; + for (int i = 0; i < literals.length-1; i++) { + value = hash.applyAsLong(value); + buffer.append(literals[i]); + int funcIdx = Math.min(functions.length - 1, i); + LongFunctionThis is a variant of Concat which always uses the input cycle value + * as the input for all the functions provided.
+ */ +@ThreadSafeMapper +@Categories(Category.general) +public class ConcatCycle extends Concat { + + public ConcatCycle(String template, Object... functions) { + super((c,s) -> c, template, functions); + } +} diff --git a/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatFixed.java b/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatFixed.java new file mode 100644 index 000000000..859a1b8e3 --- /dev/null +++ b/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatFixed.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 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.virtdata.library.basics.shared.from_long.to_string; + +import io.nosqlbench.virtdata.api.annotations.Categories; +import io.nosqlbench.virtdata.api.annotations.Category; +import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper; +import io.nosqlbench.virtdata.api.bindings.VirtDataConversions; + +import java.util.function.LongUnaryOperator; + +/** + *This is a variant of Concat which always uses the same value + * as input for the functions provided.
+ */ +@ThreadSafeMapper +@Categories(Category.general) +public class ConcatFixed extends Concat { + + public ConcatFixed(long value, String template, Object... functions) { + super((c,s) -> value, template, functions); + } +} diff --git a/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatHashed.java b/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatHashed.java new file mode 100644 index 000000000..df40a5a99 --- /dev/null +++ b/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatHashed.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 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.virtdata.library.basics.shared.from_long.to_string; + +import io.nosqlbench.virtdata.api.annotations.Categories; +import io.nosqlbench.virtdata.api.annotations.Category; +import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper; +import io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.Hash; + +/** + *This is a variant of Concat which always hashes the cycle+step value + * for each function provided.
+ */ +@ThreadSafeMapper +@Categories(Category.general) +public class ConcatHashed extends Concat { + private final static Hash hash = new Hash(); + public ConcatHashed(String template, Object... functions) { + super((c,s) -> hash.applyAsLong(c+s), template, functions); + } +} diff --git a/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatStepped.java b/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatStepped.java new file mode 100644 index 000000000..df0bbbc74 --- /dev/null +++ b/virtdata-lib-basics/src/main/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatStepped.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 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.virtdata.library.basics.shared.from_long.to_string; + +import io.nosqlbench.virtdata.api.annotations.Categories; +import io.nosqlbench.virtdata.api.annotations.Category; +import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper; +import io.nosqlbench.virtdata.api.bindings.VirtDataConversions; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.LongBinaryOperator; +import java.util.function.LongFunction; +import java.util.regex.Matcher; + +/** + *This is a variant of Concat which uses the cycle+step sum for each + * of the functions provided.
+ */ +@ThreadSafeMapper +@Categories(Category.general) +public class ConcatStepped extends Concat { + + public ConcatStepped(String template, Object... functions) { + super(Long::sum, template, functions); + } +} diff --git a/virtdata-lib-basics/src/test/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatTest.java b/virtdata-lib-basics/src/test/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatTest.java new file mode 100644 index 000000000..ae39c8ab4 --- /dev/null +++ b/virtdata-lib-basics/src/test/java/io/nosqlbench/virtdata/library/basics/shared/from_long/to_string/ConcatTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 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.virtdata.library.basics.shared.from_long.to_string; + +import io.nosqlbench.virtdata.library.basics.shared.conversions.from_long.ToHexString; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class ConcatTest { + + @Test + public void testEmptyString() { + Concat p = new Concat(""); + assertThat(p.apply(3L)).isEqualTo(""); + } + + @Test + public void testMismatchedInserts() { + Concat c = new Concat("{}"); + assertThat(c.apply(3L)).isEqualTo("v:3"); + } + + @Test + public void testOnlyLiteral() { + Concat l = new Concat(Long::sum, "literal"); + assertThat(l.apply(3L)).isEqualTo("literal"); + } + @Test + public void testSimpleValue() { + Concat p = new Concat(Long::sum, "{}", new NumberNameToString()); + assertThat(p.apply(1)).isEqualTo("one"); + } + + @Test + public void testFixedCycle() { + Concat p = new Concat((c, s) -> c, "{}-{}", new NumberNameToString()); + assertThat(p.apply(3L)).isEqualTo("three-three"); + } + + @Test + public void testSteppedCycle() { + Concat p = new Concat(Long::sum, "{}-{}", new NumberNameToString()); + assertThat(p.apply(3L)).isEqualTo("three-four"); + } + + + @Test + public void testConcatChained() { + ConcatChained cc = new ConcatChained("{}-{}", new ToHexString()); + assertThat(cc.apply(1)).isEqualTo("5752fae69d1653da-7dfbf78ca62528b5"); + } + +}