mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
Merge branch 'main' into dependabot/maven/mvn-defaults/io.netty-netty-handler-4.1.118.Final
This commit is contained in:
commit
3458a8eac1
@ -178,17 +178,17 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cassandra</groupId>
|
<groupId>org.apache.cassandra</groupId>
|
||||||
<artifactId>java-driver-core</artifactId>
|
<artifactId>java-driver-core</artifactId>
|
||||||
<version>4.18.1</version>
|
<version>4.19.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cassandra</groupId>
|
<groupId>org.apache.cassandra</groupId>
|
||||||
<artifactId>java-driver-query-builder</artifactId>
|
<artifactId>java-driver-query-builder</artifactId>
|
||||||
<version>4.18.1</version>
|
<version>4.19.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cassandra</groupId>
|
<groupId>org.apache.cassandra</groupId>
|
||||||
<artifactId>java-driver-mapper-runtime</artifactId>
|
<artifactId>java-driver-mapper-runtime</artifactId>
|
||||||
<version>4.18.1</version>
|
<version>4.19.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
|
@ -59,13 +59,11 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cassandra</groupId>
|
<groupId>org.apache.cassandra</groupId>
|
||||||
<artifactId>java-driver-core</artifactId>
|
<artifactId>java-driver-core</artifactId>
|
||||||
<version>4.18.1</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cassandra</groupId>
|
<groupId>org.apache.cassandra</groupId>
|
||||||
<artifactId>java-driver-query-builder</artifactId>
|
<artifactId>java-driver-query-builder</artifactId>
|
||||||
<version>4.18.1</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -28,33 +28,35 @@ import java.util.List;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize a vector in List<Number> form, calling the appropriate conversion function
|
Normalize a vector in List<Number> form, calling the appropriate conversion function
|
||||||
* depending on the component (Class) type of the incoming List values.
|
depending on the component (Class) type of the incoming List values. */
|
||||||
*/
|
|
||||||
@ThreadSafeMapper
|
@ThreadSafeMapper
|
||||||
@Categories(Category.experimental)
|
@Categories(Category.experimental)
|
||||||
public class NormalizeCqlVector implements Function<CqlVector, CqlVector> {
|
public class NormalizeCqlVector<N extends Number> implements Function<CqlVector<N>, CqlVector<N>> {
|
||||||
private final NormalizeDoubleListVector ndv = new NormalizeDoubleListVector();
|
private final NormalizeDoubleListVector ndv = new NormalizeDoubleListVector();
|
||||||
private final NormalizeFloatListVector nfv = new NormalizeFloatListVector();
|
private final NormalizeFloatListVector nfv = new NormalizeFloatListVector();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CqlVector apply(CqlVector cqlVector) {
|
public CqlVector apply(CqlVector<N> cqlVector) {
|
||||||
double[] vals = new double[cqlVector.size()];
|
double[] vals = new double[cqlVector.size()];
|
||||||
double accumulator= 0.0d;
|
double accumulator = 0.0d;
|
||||||
for (int i = 0; i < vals.length; i++) {
|
for (int i = 0; i < vals.length; i++) {
|
||||||
vals[i]=cqlVector.get(i).doubleValue();
|
vals[i] = cqlVector.get(i).doubleValue();
|
||||||
accumulator+=vals[i]*vals[i];
|
accumulator += vals[i] * vals[i];
|
||||||
}
|
}
|
||||||
double factor = 1.0d/Math.sqrt(Arrays.stream(vals).map(d -> d * d).sum());
|
double factor = 1.0d / Math.sqrt(Arrays.stream(vals).map(d -> d * d).sum());
|
||||||
|
|
||||||
if (cqlVector.get(0) instanceof Float) {
|
if (cqlVector.get(0) instanceof Float) {
|
||||||
List<Float> list = Arrays.stream(vals).mapToObj(d -> Float.valueOf((float) (d * factor))).toList();
|
List<Float> list =
|
||||||
|
Arrays.stream(vals).mapToObj(d -> Float.valueOf((float) (d * factor))).toList();
|
||||||
return CqlVector.newInstance(list);
|
return CqlVector.newInstance(list);
|
||||||
} else if (cqlVector.get(0) instanceof Double) {
|
} else if (cqlVector.get(0) instanceof Double) {
|
||||||
List<Double> list = Arrays.stream(vals).mapToObj(d -> Double.valueOf((float) (d * factor))).toList();
|
List<Double> list =
|
||||||
|
Arrays.stream(vals).mapToObj(d -> Double.valueOf((float) (d * factor))).toList();
|
||||||
return CqlVector.newInstance(list);
|
return CqlVector.newInstance(list);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException(NormalizeCqlVector.class.getCanonicalName()+ " only supports Double and Float type");
|
throw new RuntimeException(NormalizeCqlVector.class.getCanonicalName()
|
||||||
|
+ " only supports Double and Float type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,9 @@ public class NormalizeCqlVectorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void normalizeCqlVectorDoubles() {
|
public void normalizeCqlVectorDoubles() {
|
||||||
CqlVector square = CqlVector.newInstance(1.0d, 1.0d);
|
CqlVector<Number> square = CqlVector.newInstance(1.0d, 1.0d);
|
||||||
NormalizeCqlVector nv = new NormalizeCqlVector();
|
NormalizeCqlVector nv = new NormalizeCqlVector();
|
||||||
CqlVector normaled = nv.apply(square);
|
CqlVector<Number> normaled = nv.apply(square);
|
||||||
|
|
||||||
assertThat(normaled.size()).isEqualTo(2);
|
assertThat(normaled.size()).isEqualTo(2);
|
||||||
assertThat(normaled.get(0)).isInstanceOf(Double.class);
|
assertThat(normaled.get(0)).isInstanceOf(Double.class);
|
||||||
|
@ -118,10 +118,10 @@ public class StandardActivity<R extends java.util.function.LongFunction, S> exte
|
|||||||
} else {
|
} else {
|
||||||
adapter = adapters.get(driverName);
|
adapter = adapters.get(driverName);
|
||||||
}
|
}
|
||||||
if (adapter instanceof NBConfigurable configurable) {
|
// if (adapter instanceof NBConfigurable configurable) {
|
||||||
adapterModel = configurable.getConfigModel();
|
// adapterModel = configurable.getConfigModel();
|
||||||
adapterModel.assertValidConfig(ot.getParams());
|
// adapterModel.assertValidConfig(ot.getParams());
|
||||||
}
|
// }
|
||||||
paramsAdvisor.validateAll(ot.getParams().keySet());
|
paramsAdvisor.validateAll(ot.getParams().keySet());
|
||||||
paramsAdvisor.validateAll(ot.getTags().keySet());
|
paramsAdvisor.validateAll(ot.getTags().keySet());
|
||||||
paramsAdvisor.validateAll(ot.getBindings().keySet());
|
paramsAdvisor.validateAll(ot.getBindings().keySet());
|
||||||
|
@ -35,6 +35,7 @@ public class VirtDataFunctions {
|
|||||||
LongUnaryOperator(java.util.function.LongUnaryOperator.class, long.class),
|
LongUnaryOperator(java.util.function.LongUnaryOperator.class, long.class),
|
||||||
IntFunction(java.util.function.IntFunction.class, int.class),
|
IntFunction(java.util.function.IntFunction.class, int.class),
|
||||||
IntUnaryOperator(java.util.function.IntUnaryOperator.class, int.class),
|
IntUnaryOperator(java.util.function.IntUnaryOperator.class, int.class),
|
||||||
|
DoubleToLongFunction(java.util.function.DoubleToLongFunction.class, long.class),
|
||||||
DoubleToIntFunction(java.util.function.DoubleToIntFunction.class, int.class),
|
DoubleToIntFunction(java.util.function.DoubleToIntFunction.class, int.class),
|
||||||
DoubleFunction(java.util.function.DoubleFunction.class, double.class),
|
DoubleFunction(java.util.function.DoubleFunction.class, double.class),
|
||||||
DoubleUnaryOperator(java.util.function.DoubleUnaryOperator.class, double.class),
|
DoubleUnaryOperator(java.util.function.DoubleUnaryOperator.class, double.class),
|
||||||
@ -60,46 +61,70 @@ public class VirtDataFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapt a functional object into a different type of functional object.
|
Adapt a functional object into a different type of functional object.
|
||||||
*
|
@param func
|
||||||
* @param func The original function object.
|
The original function object.
|
||||||
* @param type The type of function object needed.
|
@param type
|
||||||
* @param output The output type required for the adapted function.
|
The type of function object needed.
|
||||||
* @param truncate Whether to throw an exception on any narrowing conversion. If this is set to false, then basic
|
@param output
|
||||||
* roll-over logic is applied on narrowing conversions.
|
The output type required for the adapted function.
|
||||||
* @param <F> The type of function object needed.
|
@param truncate
|
||||||
* @return An instance of F
|
Whether to throw an exception on any narrowing conversion. If this is set to false, then
|
||||||
|
basic
|
||||||
|
roll-over logic is applied on narrowing conversions.
|
||||||
|
@param <F>
|
||||||
|
The type of function object needed.
|
||||||
|
@return An instance of F
|
||||||
*/
|
*/
|
||||||
public static <F> F adapt(Object func, Class<F> type, Class<?> output, boolean truncate) {
|
public static <F> F adapt(Object func, Class<F> type, Class<?> output, boolean truncate) {
|
||||||
FuncType funcType = FuncType.valueOf(type);
|
FuncType funcType = FuncType.valueOf(type);
|
||||||
switch (funcType) {
|
switch (funcType) {
|
||||||
|
case DoubleToLongFunction:
|
||||||
|
return truncate ? (F) adaptDoubleToLongFunction(func, output) :
|
||||||
|
(F) adaptDoubleToLongFunctionStrict(func, output);
|
||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
return truncate ? (F) adaptLongUnaryOperator(func, output) : (F) adaptLongUnaryOperatorStrict(func, output);
|
return truncate ? (F) adaptLongUnaryOperator(func, output) :
|
||||||
|
(F) adaptLongUnaryOperatorStrict(func, output);
|
||||||
case DoubleUnaryOperator:
|
case DoubleUnaryOperator:
|
||||||
return truncate ? (F) adaptDoubleUnaryOperator(func, output) : (F) adaptDoubleUnaryOperatorStrict(func, output);
|
return truncate ? (F) adaptDoubleUnaryOperator(func, output) :
|
||||||
|
(F) adaptDoubleUnaryOperatorStrict(func, output);
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
return truncate ? adaptIntUnaryOperator(func, output) : adaptIntUnaryOperatorStrict(func, output);
|
return truncate ? adaptIntUnaryOperator(func, output) :
|
||||||
|
adaptIntUnaryOperatorStrict(func, output);
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
return truncate ? adaptDoubleFunction(func, output) : adaptDoubleFunctionStrict(func, output);
|
return truncate ? adaptDoubleFunction(func, output) :
|
||||||
|
adaptDoubleFunctionStrict(func, output);
|
||||||
case LongFunction:
|
case LongFunction:
|
||||||
return truncate ? (F) adaptLongFunction(func, output) : (F) adaptLongFunctionStrict(func, output);
|
return truncate ? (F) adaptLongFunction(func, output) :
|
||||||
|
(F) adaptLongFunctionStrict(func, output);
|
||||||
case LongToDoubleFunction:
|
case LongToDoubleFunction:
|
||||||
return truncate ? (F) adaptLongToDoubleFunction(func, output) : (F) adaptLongToDoubleFunctionStrict(func, output);
|
return truncate ? (F) adaptLongToDoubleFunction(func, output) :
|
||||||
|
(F) adaptLongToDoubleFunctionStrict(func, output);
|
||||||
case LongToIntFunction:
|
case LongToIntFunction:
|
||||||
return truncate ? (F) adaptLongToIntFunction(func, output) : (F) adaptLongFunctionStrict(func, output);
|
return truncate ? (F) adaptLongToIntFunction(func, output) :
|
||||||
|
(F) adaptLongFunctionStrict(func, output);
|
||||||
case IntFunction:
|
case IntFunction:
|
||||||
return adaptIntFunction(func, output);
|
return adaptIntFunction(func, output);
|
||||||
case Function:
|
case Function:
|
||||||
return truncate ? (F) adaptFunction(func, output) : adaptFunctionStrict(func, output);
|
return truncate ? (F) adaptFunction(func, output) :
|
||||||
|
adaptFunctionStrict(func, output);
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to convert function type '" + funcType + "' (" + func.getClass().getName() +
|
throw new RuntimeException(
|
||||||
") to " + type.getName() + (truncate ? " WITH " : " WITHOUT ") + "truncation");
|
"Unable to convert function type '" + funcType + "' (" + func.getClass()
|
||||||
|
.getName() + ") to " + type.getName() + (truncate ? " WITH " : " WITHOUT ")
|
||||||
|
+ "truncation");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static <F extends Object> List<F> adaptList(Object[] funcs, Class<F> type, Class<?> output, boolean truncate) {
|
public static <F extends Object> List<F> adaptList(
|
||||||
|
Object[] funcs,
|
||||||
|
Class<F> type,
|
||||||
|
Class<?> output,
|
||||||
|
boolean truncate
|
||||||
|
)
|
||||||
|
{
|
||||||
List<F> adapted = new ArrayList<>();
|
List<F> adapted = new ArrayList<>();
|
||||||
for (Object func : funcs) {
|
for (Object func : funcs) {
|
||||||
F f = adapt(func, type, output, truncate);
|
F f = adapt(func, type, output, truncate);
|
||||||
@ -109,7 +134,11 @@ public class VirtDataFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static LongToDoubleFunction adaptLongToDoubleFunctionStrict(Object func, Class<?> output) {
|
private static LongToDoubleFunction adaptLongToDoubleFunctionStrict(
|
||||||
|
Object func,
|
||||||
|
Class<?> output
|
||||||
|
)
|
||||||
|
{
|
||||||
FuncType isaType = FuncType.valueOf(func.getClass());
|
FuncType isaType = FuncType.valueOf(func.getClass());
|
||||||
switch (isaType) {
|
switch (isaType) {
|
||||||
case LongToDoubleFunction:
|
case LongToDoubleFunction:
|
||||||
@ -119,62 +148,117 @@ public class VirtDataFunctions {
|
|||||||
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
return f2::applyAsInt;
|
return f2::applyAsInt;
|
||||||
case LongFunction:
|
case LongFunction:
|
||||||
LongFunction<Double> f3 = assertTypesAssignable(func, LongFunction.class, double.class);
|
LongFunction<Double> f3 =
|
||||||
|
assertTypesAssignable(func, LongFunction.class, double.class);
|
||||||
return f3::apply;
|
return f3::apply;
|
||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
return f4::applyAsLong;
|
return f4::applyAsLong;
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction<Double> f7 = assertTypesAssignable(func, DoubleFunction.class, double.class);
|
DoubleFunction<Double> f7 =
|
||||||
|
assertTypesAssignable(func, DoubleFunction.class, double.class);
|
||||||
return f7::apply;
|
return f7::apply;
|
||||||
case DoubleUnaryOperator:
|
case DoubleUnaryOperator:
|
||||||
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
||||||
return f8::applyAsDouble;
|
return f8::applyAsDouble;
|
||||||
case Function:
|
case Function:
|
||||||
Function<Double, Double> f9 = assertTypesAssignable(func, Function.class, double.class, double.class);
|
Function<Double, Double> f9 =
|
||||||
|
assertTypesAssignable(func, Function.class, double.class, double.class);
|
||||||
return l -> f9.apply((double) l).doubleValue();
|
return l -> f9.apply((double) l).doubleValue();
|
||||||
case IntFunction:
|
case IntFunction:
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
throwNarrowingError(func, isaType.functionClazz);
|
throwNarrowingError(func, isaType.functionClazz);
|
||||||
default:
|
default:
|
||||||
throw new BasicError("I don't know how to convert a " + func.getClass().getName() + " function to a LongToDoubleFunction.");
|
throw new BasicError("I don't know how to convert a " + func.getClass().getName()
|
||||||
|
+ " function to a LongToDoubleFunction.");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DoubleToLongFunction adaptDoubleToLongFunction(Object func, Class<?> output) {
|
||||||
|
FuncType isaType = FuncType.valueOf(func.getClass());
|
||||||
|
switch (isaType) {
|
||||||
|
case LongToDoubleFunction:
|
||||||
|
LongToDoubleFunction f1 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
||||||
|
return l -> (long) f1.applyAsDouble((long) l);
|
||||||
|
case LongToIntFunction:
|
||||||
|
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
|
return l -> f2.applyAsInt((long) l);
|
||||||
|
case LongFunction:
|
||||||
|
LongFunction<Long> f3 = assertTypesAssignable(func, LongFunction.class, Long.class);
|
||||||
|
return l -> f3.apply((long) l);
|
||||||
|
case LongUnaryOperator:
|
||||||
|
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
|
return l -> f4.applyAsLong((long) l);
|
||||||
|
case IntFunction:
|
||||||
|
IntFunction<Long> f5 = assertTypesAssignable(func, IntFunction.class, Long.class);
|
||||||
|
return l -> f5.apply((int) l);
|
||||||
|
case IntUnaryOperator:
|
||||||
|
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
|
||||||
|
return l -> f6.applyAsInt((int) l);
|
||||||
|
case DoubleToLongFunction:
|
||||||
|
DoubleToLongFunction f7 = assertTypesAssignable(func, DoubleToLongFunction.class);
|
||||||
|
return l -> f7.applyAsLong((long) l);
|
||||||
|
case DoubleToIntFunction:
|
||||||
|
DoubleToIntFunction f8 = assertTypesAssignable(func, DoubleToIntFunction.class);
|
||||||
|
return l -> f8.applyAsInt((int) l);
|
||||||
|
case DoubleFunction:
|
||||||
|
DoubleFunction<Long> f9 =
|
||||||
|
assertTypesAssignable(func, DoubleFunction.class, Long.class);
|
||||||
|
return f9::apply;
|
||||||
|
case DoubleUnaryOperator:
|
||||||
|
DoubleUnaryOperator f10 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
||||||
|
return l -> (long) f10.applyAsDouble(l);
|
||||||
|
case Function:
|
||||||
|
Function<Double, Long> f11 =
|
||||||
|
assertTypesAssignable(func, Function.class, Double.class, Long.class);
|
||||||
|
return f11::apply;
|
||||||
|
default:
|
||||||
|
throw new BasicError("I don't know how to convert a " + func.getClass().getName()
|
||||||
|
+ " function to a DoubleToLongFunction.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static LongToDoubleFunction adaptLongToDoubleFunction(Object func, Class<?> output) {
|
private static LongToDoubleFunction adaptLongToDoubleFunction(Object func, Class<?> output) {
|
||||||
FuncType isaType = FuncType.valueOf(func.getClass());
|
FuncType isaType = FuncType.valueOf(func.getClass());
|
||||||
switch (isaType) {
|
switch (isaType) {
|
||||||
case LongToDoubleFunction:
|
case LongToDoubleFunction:
|
||||||
LongToDoubleFunction f1 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
return assertTypesAssignable(func, LongToDoubleFunction.class);
|
||||||
return null;
|
|
||||||
case LongToIntFunction:
|
case LongToIntFunction:
|
||||||
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
return null;
|
return f2::applyAsInt;
|
||||||
case LongFunction:
|
case LongFunction:
|
||||||
LongFunction<Double> f3 = assertTypesAssignable(func, LongFunction.class, double.class);
|
LongFunction<Double> f3 =
|
||||||
return null;
|
assertTypesAssignable(func, LongFunction.class, double.class);
|
||||||
|
return f3::apply;
|
||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
return null;
|
return f4::applyAsLong;
|
||||||
case IntFunction:
|
case IntFunction:
|
||||||
IntFunction<Double> f5 = assertTypesAssignable(func, IntFunction.class, double.class);
|
IntFunction<Double> f5 =
|
||||||
return null;
|
assertTypesAssignable(func, IntFunction.class, double.class);
|
||||||
|
return l -> f5.apply((int) l);
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
|
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
|
||||||
return null;
|
return operand -> f6.applyAsInt((int) operand);
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction<Double> f7 = assertTypesAssignable(func, DoubleFunction.class, double.class);
|
DoubleFunction<Double> f7 =
|
||||||
return null;
|
assertTypesAssignable(func, DoubleFunction.class, double.class);
|
||||||
|
return f7::apply;
|
||||||
case DoubleUnaryOperator:
|
case DoubleUnaryOperator:
|
||||||
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
||||||
return null;
|
return f8::applyAsDouble;
|
||||||
case Function:
|
case Function:
|
||||||
Function<Double, Double> f9 = assertTypesAssignable(func, Function.class, double.class, double.class);
|
Function<Double, Double> f9 =
|
||||||
return null;
|
assertTypesAssignable(func, Function.class, double.class, double.class);
|
||||||
|
return t -> f9.apply((double) t);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new BasicError("I don't know how to convert a " + func.getClass().getName() + " function to a LongToDoubleFunction.");
|
throw new BasicError("I don't know how to convert a " + func.getClass().getName()
|
||||||
|
+ " function to a LongToDoubleFunction.");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,15 +272,32 @@ public class VirtDataFunctions {
|
|||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
LongUnaryOperator f2 = assertTypesAssignable(func, LongUnaryOperator.class);
|
LongUnaryOperator f2 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
return f2::applyAsLong;
|
return f2::applyAsLong;
|
||||||
|
case LongToDoubleFunction:
|
||||||
|
LongToDoubleFunction f7 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
||||||
|
return f7::applyAsDouble;
|
||||||
case LongToIntFunction:
|
case LongToIntFunction:
|
||||||
LongToIntFunction f3 = assertTypesAssignable(func, LongToIntFunction.class);
|
LongToIntFunction f3 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
return f3::applyAsInt;
|
return f3::applyAsInt;
|
||||||
|
case DoubleToLongFunction:
|
||||||
|
DoubleToLongFunction f4 = assertTypesAssignable(func, DoubleToLongFunction.class);
|
||||||
|
return f4::applyAsLong;
|
||||||
|
case DoubleToIntFunction:
|
||||||
|
DoubleToIntFunction f5 = assertTypesAssignable(func, DoubleToIntFunction.class);
|
||||||
|
return f5::applyAsInt;
|
||||||
|
case DoubleFunction:
|
||||||
|
DoubleFunction<?> f6 = assertTypesAssignable(func, DoubleFunction.class);
|
||||||
|
return f6::apply;
|
||||||
case Function:
|
case Function:
|
||||||
Function<Long, Long> f7 = assertTypesAssignable(func, Function.class, Long.class);
|
Function<Long, Long> f8 = assertTypesAssignable(func, Function.class, Long.class);
|
||||||
return (long l) -> f7.apply(l);
|
return f8::apply;
|
||||||
|
case DoubleUnaryOperator:
|
||||||
|
case IntUnaryOperator:
|
||||||
|
case IntFunction:
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
|
throw new RuntimeException(
|
||||||
LongUnaryOperator.class.getName() + " since this would cause a narrowing conversion.");
|
"Unable to convert " + func.getClass().getName() + " to a "
|
||||||
|
+ LongUnaryOperator.class.getName()
|
||||||
|
+ " since this would cause a narrowing conversion.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -206,48 +307,60 @@ public class VirtDataFunctions {
|
|||||||
switch (isaType) {
|
switch (isaType) {
|
||||||
case LongFunction:
|
case LongFunction:
|
||||||
LongFunction<?> f1 = (LongFunction<?>) func;
|
LongFunction<?> f1 = (LongFunction<?>) func;
|
||||||
Function<Long, ?> rf1 = f1::apply;
|
return (Function<Long, ?>) f1::apply;
|
||||||
return rf1;
|
|
||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
LongUnaryOperator f2 = (LongUnaryOperator) func;
|
LongUnaryOperator f2 = (LongUnaryOperator) func;
|
||||||
Function<Long, Long> rf2 = f2::applyAsLong;
|
return (Function<Long, Long>) f2::applyAsLong;
|
||||||
return rf2;
|
|
||||||
case IntFunction:
|
case IntFunction:
|
||||||
IntFunction f3 = (IntFunction) func;
|
IntFunction<?> f3 = (IntFunction<?>) func;
|
||||||
Function<Integer, ?> rf3 = f3::apply;
|
return (Function<Integer, ?>) f3::apply;
|
||||||
return rf3;
|
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
IntUnaryOperator f4 = (IntUnaryOperator) func;
|
IntUnaryOperator f4 = (IntUnaryOperator) func;
|
||||||
Function<Integer, ?> rf4 = f4::applyAsInt;
|
return (Function<Integer, ?>) f4::applyAsInt;
|
||||||
return rf4;
|
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction f5 = (DoubleFunction) func;
|
DoubleFunction<?> f5 = (DoubleFunction<?>) func;
|
||||||
Function<Double, ?> rf5 = f5::apply;
|
return (Function<Double, ?>) f5::apply;
|
||||||
return rf5;
|
|
||||||
case DoubleUnaryOperator:
|
case DoubleUnaryOperator:
|
||||||
DoubleUnaryOperator f6 = (DoubleUnaryOperator) func;
|
DoubleUnaryOperator f6 = (DoubleUnaryOperator) func;
|
||||||
Function<Double, ?> rf6 = f6::applyAsDouble;
|
return (Function<Double, ?>) f6::applyAsDouble;
|
||||||
return rf6;
|
case LongToDoubleFunction:
|
||||||
|
LongToDoubleFunction f10 = (LongToDoubleFunction) func;
|
||||||
|
return (Function<Long, Double>) f10;
|
||||||
case LongToIntFunction:
|
case LongToIntFunction:
|
||||||
LongToIntFunction f7 = (LongToIntFunction) func;
|
LongToIntFunction f7 = (LongToIntFunction) func;
|
||||||
Function<Long, Integer> rf7 = f7::applyAsInt;
|
Function<Long, Integer> rf7 = f7::applyAsInt;
|
||||||
case Function:
|
case Function:
|
||||||
return (Function<?, ?>) func;
|
return (Function<?, ?>) func;
|
||||||
|
case DoubleToLongFunction:
|
||||||
|
DoubleToLongFunction f8 = (DoubleToLongFunction) func;
|
||||||
|
return (Function<Double, Long>) f8::applyAsLong;
|
||||||
|
case DoubleToIntFunction:
|
||||||
|
DoubleToIntFunction f9 = (DoubleToIntFunction) func;
|
||||||
|
return (Function<Double, Integer>) f9;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to map function:" + func);
|
throw new RuntimeException("Unable to map function:" + func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <F> F adaptFunctionStrict(Object func, Class<?> output) {
|
private static <F> F adaptFunctionStrict(Object func, Class<?> output) {
|
||||||
throw new RuntimeException("This must be implemented, now that it is used: adaptFunctionsStrict(Object,Class<?>)");
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptFunctionsStrict(Object,Class<?>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <F> F adaptDoubleFunctionStrict(Object func, Class<?> output) {
|
private static <F> F adaptDoubleFunctionStrict(Object func, Class<?> output) {
|
||||||
throw new RuntimeException("This must be implemented, now that it is used: adaptDoubleFunctionStrict(Object,Class<?>) ");
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptDoubleFunctionStrict(Object,Class<?>) ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static LongFunction<?> adaptDoubleToLongFunctionStrict(Object func, Class<?> output) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptDoubleToLongFunctionStrict(Object,Class<?>)");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static <F> F adaptIntUnaryOperatorStrict(Object func, Class<?> output) {
|
private static <F> F adaptIntUnaryOperatorStrict(Object func, Class<?> output) {
|
||||||
throw new RuntimeException("This must be implemented, now that it is used: adaptIntUnaryOperatorStrict(Object,Class<?>)");
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptIntUnaryOperatorStrict(Object,Class<?>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DoubleUnaryOperator adaptDoubleUnaryOperator(Object func, Class<?> output) {
|
private static DoubleUnaryOperator adaptDoubleUnaryOperator(Object func, Class<?> output) {
|
||||||
@ -255,7 +368,8 @@ public class VirtDataFunctions {
|
|||||||
switch (toFuncType) {
|
switch (toFuncType) {
|
||||||
|
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction<Double> f2 = assertTypesAssignable(func, DoubleFunction.class, double.class);
|
DoubleFunction<Double> f2 =
|
||||||
|
assertTypesAssignable(func, DoubleFunction.class, double.class);
|
||||||
return f2::apply;
|
return f2::apply;
|
||||||
case LongToDoubleFunction:
|
case LongToDoubleFunction:
|
||||||
LongToDoubleFunction f3 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
LongToDoubleFunction f3 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
||||||
@ -264,13 +378,15 @@ public class VirtDataFunctions {
|
|||||||
LongToIntFunction f4 = assertTypesAssignable(func, LongToIntFunction.class);
|
LongToIntFunction f4 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
return l -> f4.applyAsInt((long) l % Long.MAX_VALUE);
|
return l -> f4.applyAsInt((long) l % Long.MAX_VALUE);
|
||||||
case LongFunction:
|
case LongFunction:
|
||||||
LongFunction<Double> f5 = assertTypesAssignable(func, LongFunction.class, double.class);
|
LongFunction<Double> f5 =
|
||||||
|
assertTypesAssignable(func, LongFunction.class, double.class);
|
||||||
return l -> (double) f5.apply((long) l % Long.MAX_VALUE);
|
return l -> (double) f5.apply((long) l % Long.MAX_VALUE);
|
||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
LongUnaryOperator f6 = assertTypesAssignable(func, LongUnaryOperator.class);
|
LongUnaryOperator f6 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
return l -> f6.applyAsLong((long) l % Long.MAX_VALUE);
|
return l -> f6.applyAsLong((long) l % Long.MAX_VALUE);
|
||||||
case IntFunction:
|
case IntFunction:
|
||||||
IntFunction<Double> f7 = assertTypesAssignable(func, IntFunction.class, double.class);
|
IntFunction<Double> f7 =
|
||||||
|
assertTypesAssignable(func, IntFunction.class, double.class);
|
||||||
return l -> (double) f7.apply((int) l % Integer.MAX_VALUE);
|
return l -> (double) f7.apply((int) l % Integer.MAX_VALUE);
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
IntUnaryOperator f8 = assertTypesAssignable(func, IntUnaryOperator.class);
|
IntUnaryOperator f8 = assertTypesAssignable(func, IntUnaryOperator.class);
|
||||||
@ -282,25 +398,31 @@ public class VirtDataFunctions {
|
|||||||
DoubleUnaryOperator fA = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
DoubleUnaryOperator fA = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
||||||
return fA;
|
return fA;
|
||||||
case Function:
|
case Function:
|
||||||
Function<Double, Double> f1 = assertTypesAssignable(func, Function.class, double.class, double.class);
|
Function<Double, Double> f1 =
|
||||||
|
assertTypesAssignable(func, Function.class, double.class, double.class);
|
||||||
return f1::apply;
|
return f1::apply;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unexpected value: " + toFuncType);
|
throw new IllegalStateException("Unexpected value: " + toFuncType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DoubleUnaryOperator adaptDoubleUnaryOperatorStrict(Object func, Class<?> output) {
|
private static DoubleUnaryOperator adaptDoubleUnaryOperatorStrict(Object func, Class<?> output)
|
||||||
|
{
|
||||||
FuncType toFuncType = FuncType.valueOf(func.getClass());
|
FuncType toFuncType = FuncType.valueOf(func.getClass());
|
||||||
switch (toFuncType) {
|
switch (toFuncType) {
|
||||||
case Function:
|
case Function:
|
||||||
Function<Double, Double> f1 = assertTypesAssignable(func, Function.class, double.class, double.class);
|
Function<Double, Double> f1 =
|
||||||
|
assertTypesAssignable(func, Function.class, double.class, double.class);
|
||||||
return f1::apply;
|
return f1::apply;
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction<Double> f2 = assertTypesAssignable(func, DoubleFunction.class, double.class);
|
DoubleFunction<Double> f2 =
|
||||||
|
assertTypesAssignable(func, DoubleFunction.class, double.class);
|
||||||
return f2::apply;
|
return f2::apply;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
|
throw new RuntimeException(
|
||||||
DoubleUnaryOperator.class.getName() + " since this would cause a narrowing conversion.");
|
"Unable to convert " + func.getClass().getName() + " to a "
|
||||||
|
+ DoubleUnaryOperator.class.getName()
|
||||||
|
+ " since this would cause a narrowing conversion.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,16 +437,20 @@ public class VirtDataFunctions {
|
|||||||
LongUnaryOperator o5 = assertTypesAssignable(func, LongUnaryOperator.class);
|
LongUnaryOperator o5 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
return o5;
|
return o5;
|
||||||
case Function:
|
case Function:
|
||||||
Function<Long, Long> o7 = assertTypesAssignable(func, Function.class, long.class, long.class);
|
Function<Long, Long> o7 =
|
||||||
|
assertTypesAssignable(func, Function.class, long.class, long.class);
|
||||||
return o7::apply;
|
return o7::apply;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
|
throw new RuntimeException(
|
||||||
LongUnaryOperator.class.getName() + " since this would cause a narrowing conversion.");
|
"Unable to convert " + func.getClass().getName() + " to a "
|
||||||
|
+ LongUnaryOperator.class.getName()
|
||||||
|
+ " since this would cause a narrowing conversion.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <F> F adaptIntFunction(Object func, Class<?> output) {
|
private static <F> F adaptIntFunction(Object func, Class<?> output) {
|
||||||
throw new RuntimeException("This must be implemented, now that it is used: adaptIntFunction(Object,Class<?>)");
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptIntFunction(Object,Class<?>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static LongToIntFunction adaptLongToIntFunction(Object func, Class<?> output) {
|
protected static LongToIntFunction adaptLongToIntFunction(Object func, Class<?> output) {
|
||||||
@ -332,31 +458,36 @@ public class VirtDataFunctions {
|
|||||||
|
|
||||||
switch (isaType) {
|
switch (isaType) {
|
||||||
case LongToDoubleFunction:
|
case LongToDoubleFunction:
|
||||||
LongToDoubleFunction f1 = assertTypesAssignable(func, LongToDoubleFunction.class, double.class);
|
LongToDoubleFunction f1 =
|
||||||
|
assertTypesAssignable(func, LongToDoubleFunction.class, double.class);
|
||||||
return l -> (int) (f1.applyAsDouble(l) % Integer.MAX_VALUE);
|
return l -> (int) (f1.applyAsDouble(l) % Integer.MAX_VALUE);
|
||||||
case LongToIntFunction:
|
case LongToIntFunction:
|
||||||
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
return f2;
|
return f2;
|
||||||
case LongFunction:
|
case LongFunction:
|
||||||
LongFunction<Double> f3 = assertTypesAssignable(func, LongFunction.class, double.class);
|
LongFunction<Double> f3 =
|
||||||
|
assertTypesAssignable(func, LongFunction.class, double.class);
|
||||||
return l -> (int) f3.apply((int) l % Integer.MAX_VALUE).longValue();
|
return l -> (int) f3.apply((int) l % Integer.MAX_VALUE).longValue();
|
||||||
case LongUnaryOperator:
|
case LongUnaryOperator:
|
||||||
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
|
||||||
return l -> (int) (f4.applyAsLong(l) % Integer.MAX_VALUE);
|
return l -> (int) (f4.applyAsLong(l) % Integer.MAX_VALUE);
|
||||||
case IntFunction:
|
case IntFunction:
|
||||||
IntFunction<Long> f5 = assertTypesAssignable(func, IntFunction.class, double.class);
|
IntFunction<Long> f5 = assertTypesAssignable(func, IntFunction.class, double.class);
|
||||||
return l -> (int) f5.apply((int) l % Integer.MAX_VALUE).longValue() % Integer.MAX_VALUE;
|
return l -> (int) f5.apply((int) l % Integer.MAX_VALUE).longValue()
|
||||||
|
% Integer.MAX_VALUE;
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
|
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
|
||||||
return l -> f6.applyAsInt((int) l % Integer.MAX_VALUE);
|
return l -> f6.applyAsInt((int) l % Integer.MAX_VALUE);
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction<Double> f7 = assertTypesAssignable(func, DoubleFunction.class, double.class);
|
DoubleFunction<Double> f7 =
|
||||||
|
assertTypesAssignable(func, DoubleFunction.class, double.class);
|
||||||
return l -> (int) f7.apply(l).longValue() & Integer.MAX_VALUE;
|
return l -> (int) f7.apply(l).longValue() & Integer.MAX_VALUE;
|
||||||
case DoubleUnaryOperator:
|
case DoubleUnaryOperator:
|
||||||
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
||||||
return l -> (int) f8.applyAsDouble(l) % Integer.MAX_VALUE;
|
return l -> (int) f8.applyAsDouble(l) % Integer.MAX_VALUE;
|
||||||
case Function:
|
case Function:
|
||||||
Function<Double, Double> f9 = assertTypesAssignable(func, Function.class, double.class, double.class);
|
Function<Double, Double> f9 =
|
||||||
|
assertTypesAssignable(func, Function.class, double.class, double.class);
|
||||||
return l -> (int) f9.apply((double) l).longValue() % Integer.MAX_VALUE;
|
return l -> (int) f9.apply((double) l).longValue() % Integer.MAX_VALUE;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unexpected value: " + isaType);
|
throw new IllegalStateException("Unexpected value: " + isaType);
|
||||||
@ -397,29 +528,33 @@ public class VirtDataFunctions {
|
|||||||
assertOutputAssignable(f9.applyAsInt(1L), output);
|
assertOutputAssignable(f9.applyAsInt(1L), output);
|
||||||
return (long l) -> f9.applyAsInt(l);
|
return (long l) -> f9.applyAsInt(l);
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
|
throw new RuntimeException(
|
||||||
LongUnaryOperator.class.getName());
|
"Unable to convert " + func.getClass().getName() + " to a "
|
||||||
|
+ LongUnaryOperator.class.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertOutputAssignable(Object result, Class<?> clazz) {
|
private static void assertOutputAssignable(Object result, Class<?> clazz) {
|
||||||
if (!ClassUtils.isAssignable(result.getClass(), clazz, true)) {
|
if (!ClassUtils.isAssignable(result.getClass(), clazz, true)) {
|
||||||
throw new InvalidParameterException("Unable to assign type of " + result.getClass().getName()
|
throw new InvalidParameterException(
|
||||||
+ " to " + clazz.getName());
|
"Unable to assign type of " + result.getClass().getName() + " to "
|
||||||
|
+ clazz.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!clazz.isAssignableFrom(result.getClass())) {
|
// if (!clazz.isAssignableFrom(result.getClass())) {
|
||||||
// throw new InvalidParameterException("Unable to assign type of " + result.getClass().getName()
|
// throw new InvalidParameterException("Unable to assign type of " + result.getClass().getName()
|
||||||
// + " to " + clazz.getName());
|
// + " to " + clazz.getName());
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <F> F adaptDoubleFunction(Object func, Class<?> output) {
|
private static <F> F adaptDoubleFunction(Object func, Class<?> output) {
|
||||||
throw new RuntimeException("This must be implemented, now that it is used: adaptDoubleFunction(Object,Class<?>)");
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptDoubleFunction(Object,Class<?>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <F> F adaptIntUnaryOperator(Object func, Class<?> output) {
|
private static <F> F adaptIntUnaryOperator(Object func, Class<?> output) {
|
||||||
throw new RuntimeException("This must be implemented, now that it is used: adaptIntUnaryOperator(Object,Class<?>)");
|
throw new RuntimeException(
|
||||||
|
"This must be implemented, now that it is used: adaptIntUnaryOperator(Object,Class<?>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -434,7 +569,8 @@ public class VirtDataFunctions {
|
|||||||
LongFunction<Long> o2 = assertTypesAssignable(func, LongFunction.class, long.class);
|
LongFunction<Long> o2 = assertTypesAssignable(func, LongFunction.class, long.class);
|
||||||
return o2::apply;
|
return o2::apply;
|
||||||
case DoubleFunction:
|
case DoubleFunction:
|
||||||
DoubleFunction<Long> o3 = assertTypesAssignable(func, DoubleFunction.class, long.class);
|
DoubleFunction<Long> o3 =
|
||||||
|
assertTypesAssignable(func, DoubleFunction.class, long.class);
|
||||||
return o3::apply;
|
return o3::apply;
|
||||||
case IntUnaryOperator:
|
case IntUnaryOperator:
|
||||||
IntUnaryOperator o4 = assertTypesAssignable(func, IntUnaryOperator.class);
|
IntUnaryOperator o4 = assertTypesAssignable(func, IntUnaryOperator.class);
|
||||||
@ -446,7 +582,8 @@ public class VirtDataFunctions {
|
|||||||
DoubleUnaryOperator o6 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
DoubleUnaryOperator o6 = assertTypesAssignable(func, DoubleUnaryOperator.class);
|
||||||
return (long l) -> (long) (o6.applyAsDouble(l) % Long.MAX_VALUE);
|
return (long l) -> (long) (o6.applyAsDouble(l) % Long.MAX_VALUE);
|
||||||
case Function:
|
case Function:
|
||||||
Function<Long, Long> o7 = assertTypesAssignable(func, Function.class, long.class, long.class);
|
Function<Long, Long> o7 =
|
||||||
|
assertTypesAssignable(func, Function.class, long.class, long.class);
|
||||||
return o7::apply;
|
return o7::apply;
|
||||||
case LongToDoubleFunction:
|
case LongToDoubleFunction:
|
||||||
LongToDoubleFunction o8 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
LongToDoubleFunction o8 = assertTypesAssignable(func, LongToDoubleFunction.class);
|
||||||
@ -455,49 +592,60 @@ public class VirtDataFunctions {
|
|||||||
LongToIntFunction o9 = assertTypesAssignable(func, LongToIntFunction.class);
|
LongToIntFunction o9 = assertTypesAssignable(func, LongToIntFunction.class);
|
||||||
return o9::applyAsInt;
|
return o9::applyAsInt;
|
||||||
}
|
}
|
||||||
throw new InvalidParameterException("Unable to convert " + func.getClass().getName() + " to a " +
|
throw new InvalidParameterException(
|
||||||
LongUnaryOperator.class.getName());
|
"Unable to convert " + func.getClass().getName() + " to a "
|
||||||
|
+ LongUnaryOperator.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a base object and a wanted type to convert it to, assert that the type of the base object is assignable to
|
Given a base object and a wanted type to convert it to, assert that the type of the base object
|
||||||
* the wanted type. Further, if the wanted type is a generic type, assert that additional classes are assignable to
|
is assignable to
|
||||||
* the generic type parameters. Thus, if you want to assign to a generic type from a non-generic type, you must
|
the wanted type. Further, if the wanted type is a generic type, assert that additional classes
|
||||||
* qualify the types of values that will be used in those generic parameter positions in declaration order.
|
are assignable to
|
||||||
*
|
the generic type parameters. Thus, if you want to assign to a generic type from a non-generic
|
||||||
* <p>This is useful for taking any object and a known type and reifying it as the known type so that it can be
|
type, you must
|
||||||
* then used idiomatically with normal type awareness. This scenario occurs when you are accepting an open type for
|
qualify the types of values that will be used in those generic parameter positions in
|
||||||
* flexibility but then need to narrow the type sufficiently for additional conversion in a type-safe way.</p>
|
declaration order.
|
||||||
*
|
|
||||||
* @param base The object to be assigned to the wanted type
|
<p>This is useful for taking any object and a known type and reifying it as the known type so
|
||||||
* @param wantType The class type that the base object needs to be assignable to
|
that it can be
|
||||||
* @param clazzes The types of values which will checked against generic type parameters of the wanted type
|
then used idiomatically with normal type awareness. This scenario occurs when you are accepting
|
||||||
* @param <T> Generic parameter T for the wanted type
|
an open type for
|
||||||
* @return The original object casted to the wanted type after verification of parameter assignability
|
flexibility but then need to narrow the type sufficiently for additional conversion in a
|
||||||
|
type-safe way.</p>
|
||||||
|
@param base
|
||||||
|
The object to be assigned to the wanted type
|
||||||
|
@param wantType
|
||||||
|
The class type that the base object needs to be assignable to
|
||||||
|
@param clazzes
|
||||||
|
The types of values which will checked against generic type parameters of the wanted type
|
||||||
|
@param <T>
|
||||||
|
Generic parameter T for the wanted type
|
||||||
|
@return The original object casted to the wanted type after verification of parameter assignability
|
||||||
*/
|
*/
|
||||||
private static <T> T assertTypesAssignable(
|
private static <T> T assertTypesAssignable(Object base, Class<T> wantType, Class<?>... clazzes)
|
||||||
Object base,
|
{
|
||||||
Class<T> wantType,
|
|
||||||
Class<?>... clazzes) {
|
|
||||||
|
|
||||||
if (!wantType.isAssignableFrom(base.getClass())) {
|
if (!wantType.isAssignableFrom(base.getClass())) {
|
||||||
throw new InvalidParameterException("Unable to assign " + wantType.getName() + " from " +
|
throw new InvalidParameterException(
|
||||||
base.getClass().getName());
|
"Unable to assign " + wantType.getName() + " from " + base.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeVariable<? extends Class<?>>[] typeParameters = base.getClass().getTypeParameters();
|
TypeVariable<? extends Class<?>>[] typeParameters = base.getClass().getTypeParameters();
|
||||||
if (typeParameters.length > 0) {
|
if (typeParameters.length > 0) {
|
||||||
if (clazzes.length != typeParameters.length) {
|
if (clazzes.length != typeParameters.length) {
|
||||||
throw new InvalidParameterException(
|
throw new InvalidParameterException(
|
||||||
"type parameter lengths are mismatched:" + clazzes.length + ", " + typeParameters.length
|
"type parameter lengths are mismatched:" + clazzes.length + ", "
|
||||||
);
|
+ typeParameters.length);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < clazzes.length; i++) {
|
for (int i = 0; i < clazzes.length; i++) {
|
||||||
Class<?> from = clazzes[i];
|
Class<?> from = clazzes[i];
|
||||||
TypeVariable<? extends Class<?>> to = typeParameters[i];
|
TypeVariable<? extends Class<?>> to = typeParameters[i];
|
||||||
boolean assignableFrom = to.getGenericDeclaration().isAssignableFrom(from);
|
boolean assignableFrom = to.getGenericDeclaration().isAssignableFrom(from);
|
||||||
if (!assignableFrom) {
|
if (!assignableFrom) {
|
||||||
throw new InvalidParameterException("Can not assign " + from.getName() + " to " + to.getGenericDeclaration().getName());
|
throw new InvalidParameterException(
|
||||||
|
"Can not assign " + from.getName() + " to " + to.getGenericDeclaration()
|
||||||
|
.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,14 +655,16 @@ public class VirtDataFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throw an error indicating a narrowing conversion was attempted for strict conversion.
|
Throw an error indicating a narrowing conversion was attempted for strict conversion.
|
||||||
*
|
@param func
|
||||||
* @param func The source function to convert from
|
The source function to convert from
|
||||||
* @param targetClass The target class which was requested
|
@param targetClass
|
||||||
|
The target class which was requested
|
||||||
*/
|
*/
|
||||||
private static void throwNarrowingError(Object func, Class<?> targetClass) {
|
private static void throwNarrowingError(Object func, Class<?> targetClass) {
|
||||||
throw new BasicError("Converting from " + func.getClass().getName() + " to " + targetClass.getName() +
|
throw new BasicError(
|
||||||
" is not allowed when strict conversion is requested.");
|
"Converting from " + func.getClass().getName() + " to " + targetClass.getName()
|
||||||
|
+ " is not allowed when strict conversion is requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.nosqlbench.virtdata.library.basics.core.stathelpers;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.DoubleToIntFunction;
|
||||||
|
import java.util.function.DoubleToLongFunction;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses the alias sampling method to encode and sample from discrete probabilities,
|
||||||
|
* even over larger sets of data. This form requires a unit interval sample value
|
||||||
|
* between 0.0 and 1.0. Assuming the maximal amount of memory is used for distinct
|
||||||
|
* outcomes N, a memory buffer of N*16 bytes is required for this implementation,
|
||||||
|
* requiring 32MB of memory for 1M entries.
|
||||||
|
*
|
||||||
|
* This sampler should be shared between threads, and will be by default, in order
|
||||||
|
* to avoid many instances of a 32MB buffer on heap.
|
||||||
|
*/
|
||||||
|
public class AliasSamplerDoubleLong implements DoubleToLongFunction {
|
||||||
|
|
||||||
|
private final ByteBuffer stats; // tuples of double,int,int (unfair coin, direct pointers to referents)
|
||||||
|
private final double slotCount; // The number of fair die-roll slotCount that contain unfair coin probabilities
|
||||||
|
private static final int _r0=0;
|
||||||
|
private static final int _r1=_r0+Double.BYTES; // unfair coin
|
||||||
|
private static final int _r2=_r1+Long.BYTES; // + referent 1
|
||||||
|
public static int RECORD_LEN = _r2 + Long.BYTES; // + referent 2 = Record size for the above.
|
||||||
|
|
||||||
|
// for testing
|
||||||
|
AliasSamplerDoubleLong(ByteBuffer stats) {
|
||||||
|
this.stats = stats;
|
||||||
|
if ((stats.capacity()% RECORD_LEN)!=0) {
|
||||||
|
throw new RuntimeException("Misaligned ByteBuffer size, must be a multiple of " + RECORD_LEN);
|
||||||
|
}
|
||||||
|
slotCount = (stats.capacity()/ RECORD_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AliasSamplerDoubleLong(List<EvProbLongDouble> events) {
|
||||||
|
int size = events.size();
|
||||||
|
|
||||||
|
int[] alias = new int[events.size()];
|
||||||
|
double[] prob = new double[events.size()];
|
||||||
|
|
||||||
|
LinkedList<EvProbLongDouble> small = new LinkedList<>();
|
||||||
|
LinkedList<EvProbLongDouble> large = new LinkedList<>();
|
||||||
|
List<Slot> slots = new ArrayList<>();
|
||||||
|
|
||||||
|
// array-size normalization
|
||||||
|
double sumProbability = events.stream().mapToDouble(EvProbLongDouble::prob).sum();
|
||||||
|
events = events.stream().map(e -> new EvProbLongDouble(e.id(),
|
||||||
|
(e.prob()/sumProbability)*size)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// presort
|
||||||
|
for (EvProbLongDouble event : events) {
|
||||||
|
(event.prob()<1.0D ? small : large).addLast(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (small.peekFirst()!=null && large.peekFirst()!=null) {
|
||||||
|
EvProbLongDouble l = small.removeFirst();
|
||||||
|
EvProbLongDouble g = large.removeFirst();
|
||||||
|
slots.add(new Slot(g.id(), l.id(), l.prob()));
|
||||||
|
EvProbLongDouble remainder = new EvProbLongDouble(g.id(),(g.prob()+l.prob())-1);
|
||||||
|
(remainder.prob()<1.0D ? small : large).addLast(remainder);
|
||||||
|
}
|
||||||
|
while (large.peekFirst()!=null) {
|
||||||
|
EvProbLongDouble g = large.removeFirst();
|
||||||
|
slots.add(new Slot(g.id(),g.id(),1.0));
|
||||||
|
}
|
||||||
|
while (small.peekFirst()!=null) {
|
||||||
|
EvProbLongDouble l = small.removeFirst();
|
||||||
|
slots.add(new Slot(l.id(),l.id(),1.0));
|
||||||
|
}
|
||||||
|
if (slots.size()!=size) {
|
||||||
|
throw new RuntimeException("basis for average probability is incorrect, because only " + slots.size() + " slotCount of " + size + " were created.");
|
||||||
|
}
|
||||||
|
// align to indexes
|
||||||
|
for (int i = 0; i < slots.size(); i++) {
|
||||||
|
slots.set(i,slots.get(i).rescale(i, i+1));
|
||||||
|
}
|
||||||
|
this.stats = ByteBuffer.allocate(slots.size()* RECORD_LEN);
|
||||||
|
|
||||||
|
for (Slot slot : slots) {
|
||||||
|
stats.putDouble(slot.botProb);
|
||||||
|
stats.putLong(slot.botId());
|
||||||
|
stats.putLong(slot.topId());
|
||||||
|
}
|
||||||
|
stats.flip();
|
||||||
|
this.slotCount = (stats.capacity()/ RECORD_LEN);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long applyAsLong(double value) {
|
||||||
|
double fractionlPoint = value * slotCount;
|
||||||
|
int offsetPoint = (int) fractionlPoint * RECORD_LEN;
|
||||||
|
double divider = stats.getDouble(offsetPoint);
|
||||||
|
int selector = offsetPoint+ (fractionlPoint>divider?_r2:_r1);
|
||||||
|
long referentId = stats.getLong(selector);
|
||||||
|
return referentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Slot(long topId, long botId, double botProb){
|
||||||
|
public Slot rescale(int min, int max) {
|
||||||
|
return new Slot(topId, botId, (min + (botProb*(max-min))));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.nosqlbench.virtdata.library.basics.core.stathelpers;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
public record EvProbLongDouble(long id, double prob) {
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_double.to_long;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.virtdata.api.annotations.Categories;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Example;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||||
|
import io.nosqlbench.virtdata.api.bindings.VirtDataFunctions;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.AliasSamplerDoubleLong;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.EvProbLongDouble;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.EmpiricalDistribution;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.HashRange;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.DoubleToLongFunction;
|
||||||
|
import java.util.function.LongToDoubleFunction;
|
||||||
|
import java.util.function.LongUnaryOperator;
|
||||||
|
|
||||||
|
@ThreadSafeMapper
|
||||||
|
@Categories(Category.distributions)
|
||||||
|
public class IntervalHistribution implements LongUnaryOperator {
|
||||||
|
|
||||||
|
private final UnitHistribution sampler;
|
||||||
|
private final LongToDoubleFunction samplePointF;
|
||||||
|
|
||||||
|
@Example({"IntervalHistribution('50 25 13 12')", "implied frequencies of 0:50 1:25 2:13 3:12"})
|
||||||
|
@Example({
|
||||||
|
"IntervalHistribution('234:50 33:25 17:13 3:12')",
|
||||||
|
"labeled frequencies; 234,33,17,3 are labels, and 50,25,13,12 are weights"
|
||||||
|
})
|
||||||
|
public IntervalHistribution(String freqs, Object samplePointFunc) {
|
||||||
|
this.sampler = new UnitHistribution(freqs);
|
||||||
|
this.samplePointF = VirtDataFunctions.adapt(
|
||||||
|
samplePointFunc,
|
||||||
|
LongToDoubleFunction.class,
|
||||||
|
double.class,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntervalHistribution(String freqs) {
|
||||||
|
this(freqs,new HashRange(0.0d,1.0d));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static List<EvProbLongDouble> genEvents(long[] freqs) {
|
||||||
|
ArrayList<EvProbLongDouble> events = new ArrayList<>();
|
||||||
|
for (int i = 0; i < freqs.length; i++) {
|
||||||
|
events.add(new EvProbLongDouble(i, freqs[i]));
|
||||||
|
}
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long applyAsLong(long operand) {
|
||||||
|
double samplePoint = this.samplePointF.applyAsDouble(operand);
|
||||||
|
return this.sampler.applyAsLong(samplePoint);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_double.to_long;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.virtdata.api.annotations.Categories;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Example;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.AliasSamplerDoubleLong;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.EvProbLongDouble;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.EmpiricalDistribution;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.DoubleToLongFunction;
|
||||||
|
|
||||||
|
/// Empirical Histribution is a portmanteau name to capture the
|
||||||
|
/// concept of an empirical distribution based on a discrete histogram.
|
||||||
|
/// This is in contrast to the other similar method [EmpiricalDistribution],
|
||||||
|
/// which uses a continuous density estimation. Both excel in specific ways.
|
||||||
|
///
|
||||||
|
/// Use this distribution when you have a set of label frequencies which you
|
||||||
|
/// want to represent accurately.
|
||||||
|
@ThreadSafeMapper
|
||||||
|
@Categories(Category.distributions)
|
||||||
|
public class UnitHistribution extends AliasSamplerDoubleLong implements DoubleToLongFunction {
|
||||||
|
|
||||||
|
@Example({"UnitHistribution('50 25 13 12')", "implied frequencies of 0:50 1:25 2:13 3:12"})
|
||||||
|
@Example({
|
||||||
|
"UnitHistribution('234:50 33:25 17:13 3:12')",
|
||||||
|
"labeled frequencies; 234,33,17,3 are labels, and 50,25,13,12 are weights"
|
||||||
|
})
|
||||||
|
public UnitHistribution(String freqs) {
|
||||||
|
List<EvProbLongDouble> events = new ArrayList<>();
|
||||||
|
boolean labeled = (freqs.contains(":"));
|
||||||
|
|
||||||
|
String[] elems = freqs.split("[,; ]");
|
||||||
|
for (int i = 0; i < elems.length; i++) {
|
||||||
|
String[] parts = elems[i].split(":", 2);
|
||||||
|
if ((parts.length == 1 && labeled) || (parts.length == 2 && !labeled)) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"If any elements are labeled, all elements must be:" + freqs);
|
||||||
|
}
|
||||||
|
long id = labeled ? Long.parseLong(parts[0]) : i;
|
||||||
|
long weight = Long.parseLong(parts[labeled ? 1 : 0]);
|
||||||
|
events.add(new EvProbLongDouble(id, weight));
|
||||||
|
}
|
||||||
|
super(events);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public UnitHistribution(long... freqs) {
|
||||||
|
// super(genEvents(freqs));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private static List<EvProbLongDouble> genEvents(long[] freqs) {
|
||||||
|
// ArrayList<EvProbLongDouble> events = new ArrayList<>();
|
||||||
|
// for (int i = 0; i < freqs.length; i++) {
|
||||||
|
// events.add(new EvProbLongDouble(i, freqs[i]));
|
||||||
|
// }
|
||||||
|
// return events;
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_double;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.virtdata.api.annotations.Categories;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Example;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||||
|
import io.nosqlbench.virtdata.api.bindings.VirtDataConversions;
|
||||||
|
|
||||||
|
import java.util.function.LongToDoubleFunction;
|
||||||
|
import java.util.function.LongUnaryOperator;
|
||||||
|
|
||||||
|
/// Blends two functions with a domain of 0..Long.MAX_VALUE as the input interval,
|
||||||
|
/// and a double output. The output value is interpolated between the output value
|
||||||
|
/// of the two according to the mix function. When the mix function yields a value
|
||||||
|
/// of 0.0, then the mix is turned _fully counter-clockwise_., or fully on the first provided
|
||||||
|
/// function. When the value is 1.0, the mix is turned all the clockwise, or fully on the second
|
||||||
|
/// provided function.
|
||||||
|
///
|
||||||
|
/// If there are only two inner functions provided to HashMix, then it will default to
|
||||||
|
/// sampling random mixes at a randomized sample point. In other words, the variates
|
||||||
|
/// provided will be somewhere between the two curves on the unit interval. This is a simple way
|
||||||
|
/// to sample between two curves by default. The yielded value will be greater than or equal to
|
||||||
|
/// the lower of the two values at any point, and less than or equal to the greater of either.
|
||||||
|
///
|
||||||
|
/// If a third parameter is provided to control the mix, then the mix can be set directly as a
|
||||||
|
/// unit interval. (The dial goes from 0.0 to 1.0). Any double or float value here will suffice.
|
||||||
|
/// You can use this when you want to have a test parameter that slews between two modeled
|
||||||
|
/// shapes. You can alternately provide any other function which can be coerced to a LongToDouble
|
||||||
|
/// function as a dynamic mix control. IFF such a function is provided, it must also be responsible
|
||||||
|
/// for hashing the input value if pseudo-randomness is desired.
|
||||||
|
///
|
||||||
|
/// If a fourth parameter is provided, the sample point can also be controlled. By default, the
|
||||||
|
/// values on the provided curves will be sampled pseudo-randomly. However, a fourth parameter
|
||||||
|
/// can override this just like the mix ratio. As well, if you provide a value or function
|
||||||
|
/// to control the sample point, you are also responsible for any hashing needed to sample across
|
||||||
|
/// the whole space of possible values.
|
||||||
|
///
|
||||||
|
/// The flexibility of these two parameters provides a substantial amount of flexibility. You
|
||||||
|
/// can, for example:
|
||||||
|
///
|
||||||
|
/// - sample variates between two curves
|
||||||
|
/// - sample variates at a selected morphing step between the curves
|
||||||
|
/// - sample variates between two curves on a subsection of the unit interval
|
||||||
|
/// - sample variates within a defined band gap of the two curves
|
||||||
|
@ThreadSafeMapper
|
||||||
|
@Categories(Category.functional)
|
||||||
|
public class HashMix implements LongToDoubleFunction {
|
||||||
|
|
||||||
|
private final LongToDoubleFunction f1;
|
||||||
|
private final LongToDoubleFunction f2;
|
||||||
|
private final LongToDoubleFunction mixF;
|
||||||
|
private final LongUnaryOperator sampleF;
|
||||||
|
|
||||||
|
@Example({
|
||||||
|
"HashMix(Func1(),Func2())",
|
||||||
|
"yield samples between func1 and func2 values at some random random sample point x"
|
||||||
|
})
|
||||||
|
@Example({
|
||||||
|
"HashMix(Func1(),Func2(),0.25d)",
|
||||||
|
"yield samples which are 25% from the sample values for func1 and func2 at some random "
|
||||||
|
+ "sample point x"
|
||||||
|
})
|
||||||
|
@Example({
|
||||||
|
"HashMix(Func1(),Func2(),HashRange(0.25d,0.75d)",
|
||||||
|
"yield samples between 25% and 75% from func1 to func2 values at some random sample point x"
|
||||||
|
})
|
||||||
|
@Example({
|
||||||
|
"HashMix(Func1(),Func2(),0.0d,ScaledDouble())",
|
||||||
|
"access Func1 values as if it were the only one provided. ScaledDouble adds no "
|
||||||
|
+ "randomization the input value, but it does map it to the sample domain of 0.0d-0.1d."
|
||||||
|
})
|
||||||
|
public HashMix(Object curve1F, Object curve2F, Object mixPointF, Object samplePointF) {
|
||||||
|
if (mixPointF instanceof Double v) {
|
||||||
|
if (v > 1.0d || v < 0.0d) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"mix value (" + v + ") must be within the unit" + " range [0.0d,1.0d]");
|
||||||
|
}
|
||||||
|
this.mixF = n -> v;
|
||||||
|
} else if (mixPointF instanceof Float v) {
|
||||||
|
if (v > 1.0d || v < 0.0d) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"mix value (" + v + ") must be within the unit" + " range [0.0d,1.0d]");
|
||||||
|
}
|
||||||
|
this.mixF = n -> v;
|
||||||
|
} else {
|
||||||
|
this.mixF = VirtDataConversions.adaptFunction(mixPointF, LongToDoubleFunction.class);
|
||||||
|
}
|
||||||
|
this.f1 = VirtDataConversions.adaptFunction(curve1F, LongToDoubleFunction.class);
|
||||||
|
this.f2 = VirtDataConversions.adaptFunction(curve2F, LongToDoubleFunction.class);
|
||||||
|
this.sampleF = VirtDataConversions.adaptFunction(samplePointF, LongUnaryOperator.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMix(Object curve1F, Object curve2F, Object mixPointF) {
|
||||||
|
this(
|
||||||
|
curve1F,
|
||||||
|
curve2F,
|
||||||
|
mixPointF,
|
||||||
|
new io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.HashRange(Long.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMix(Object curve1F, Object curve2F) {
|
||||||
|
this(
|
||||||
|
curve1F,
|
||||||
|
curve2F,
|
||||||
|
new HashRange(0.0d, 1.0d),
|
||||||
|
new io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.HashRange(Long.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMix(LongToDoubleFunction f1, LongToDoubleFunction f2) {
|
||||||
|
this(
|
||||||
|
f1,
|
||||||
|
f2,
|
||||||
|
new HashRange(0.0d, 1.0d),
|
||||||
|
new io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.HashRange(Long.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double applyAsDouble(long value) {
|
||||||
|
long sampleAt = sampleF.applyAsLong(value);
|
||||||
|
double v1 = f1.applyAsDouble(sampleAt);
|
||||||
|
double v2 = f2.applyAsDouble(sampleAt);
|
||||||
|
double mix = mixF.applyAsDouble(value);
|
||||||
|
return LERP.lerp(v1, v2, mix);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_double;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 class LERP {
|
||||||
|
public static double lerp(double v1, double v2, double mix) {
|
||||||
|
return v1 + (v2 - v1) * mix;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_long;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.virtdata.api.annotations.Categories;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.Example;
|
||||||
|
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||||
|
|
||||||
|
import java.util.function.LongToDoubleFunction;
|
||||||
|
import java.util.function.LongUnaryOperator;
|
||||||
|
|
||||||
|
/// Blends two functions with a domain of 0..Long.MAX_VALUE as the input interval,
|
||||||
|
/// and a double output. The output value is interpolated between the output value
|
||||||
|
/// of the two according to the mix function. When the mix function yields a value
|
||||||
|
/// of 0.0, then the mix is turned _fully counter-clockwise_., or fully on the first provided
|
||||||
|
/// function. When the value is 1.0, the mix is turned all the clockwise, or fully on the second
|
||||||
|
/// provided function.
|
||||||
|
///
|
||||||
|
/// If there are only two inner functions provided to HashMix, then it will default to
|
||||||
|
/// sampling random mixes at a randomized sample point. In other words, the variates
|
||||||
|
/// provided will be somewhere between the two curves on the unit interval. This is a simple way
|
||||||
|
/// to sample between two curves by default. The yielded value will be greater than or equal to
|
||||||
|
/// the lower of the two values at any point, and less than or equal to the greater of either.
|
||||||
|
///
|
||||||
|
/// If a third parameter is provided to control the mix, then the mix can be set directly as a
|
||||||
|
/// unit interval. (The dial goes from 0.0 to 1.0). Any double or float value here will suffice.
|
||||||
|
/// You can use this when you want to have a test parameter that slews between two modeled
|
||||||
|
/// shapes. You can alternately provide any other function which can be coerced to a LongToDouble
|
||||||
|
/// function as a dynamic mix control. IFF such a function is provided, it must also be responsible
|
||||||
|
/// for hashing the input value if pseudo-randomness is desired.
|
||||||
|
///
|
||||||
|
/// If a fourth parameter is provided, the sample point can also be controlled. By default, the
|
||||||
|
/// values on the provided curves will be sampled pseudo-randomly. However, a fourth parameter
|
||||||
|
/// can override this just like the mix ratio. As well, if you provide a value or function
|
||||||
|
/// to control the sample point, you are also responsible for any hashing needed to sample across
|
||||||
|
/// the whole space of possible values.
|
||||||
|
///
|
||||||
|
/// The flexibility of these two parameters provides a substantial amount of flexibility. You
|
||||||
|
/// can, for example:
|
||||||
|
///
|
||||||
|
/// - sample variates between two curves
|
||||||
|
/// - sample variates at a selected morphing step between the curves
|
||||||
|
/// - sample variates between two curves on a subsection of the unit interval
|
||||||
|
/// - sample variates within a defined band gap of the two curves
|
||||||
|
@ThreadSafeMapper
|
||||||
|
@Categories(Category.functional)
|
||||||
|
public class HashMix implements LongUnaryOperator {
|
||||||
|
|
||||||
|
private io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.HashMix mixer;
|
||||||
|
|
||||||
|
|
||||||
|
@Example({
|
||||||
|
"IntervalHashMix(Func1(),Func2())",
|
||||||
|
"yield samples between func1 and func2 values at some random random sample point x"
|
||||||
|
})
|
||||||
|
@Example({
|
||||||
|
"IntervalHashMix(Func1(),Func2(),0.25d)",
|
||||||
|
"yield samples which are 25% from the sample values for func1 and func2 at some random "
|
||||||
|
+ "sample point x"
|
||||||
|
})
|
||||||
|
@Example({
|
||||||
|
"IntervalHashMix(Func1(),Func2(),HashRange(0.25d,0.75d)",
|
||||||
|
"yield samples between 25% and 75% from func1 to func2 values at some random sample point x"
|
||||||
|
})
|
||||||
|
@Example({
|
||||||
|
"IntervalHashMix(Func1(),Func2(),0.0d,ScaledDouble())",
|
||||||
|
"access Func1 values as if it were the only one provided. ScaledDouble adds no "
|
||||||
|
+ "randomization the input value, but it does map it to the sample domain of 0.0d-0.1d."
|
||||||
|
})
|
||||||
|
public HashMix(Object curve1F, Object curve2F, Object mixPointF, Object samplePointF) {
|
||||||
|
this.mixer = new io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.HashMix(curve1F, curve2F, mixPointF, samplePointF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMix(Object curve1F, Object curve2F, Object mixPointF) {
|
||||||
|
this(
|
||||||
|
curve1F,
|
||||||
|
curve2F,
|
||||||
|
mixPointF,
|
||||||
|
new HashRange(Long.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMix(Object curve1F, Object curve2F) {
|
||||||
|
this(
|
||||||
|
curve1F,
|
||||||
|
curve2F,
|
||||||
|
new io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.HashRange(0.0d, 1.0d),
|
||||||
|
new HashRange(Long.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMix(LongToDoubleFunction f1, LongToDoubleFunction f2) {
|
||||||
|
this(
|
||||||
|
f1,
|
||||||
|
f2,
|
||||||
|
new io.nosqlbench.virtdata.library.basics.shared.from_long.to_double.HashRange(0.0d, 1.0d),
|
||||||
|
new HashRange(Long.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long applyAsLong(long value) {
|
||||||
|
return (long) mixer.applyAsDouble(value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.nosqlbench.virtdata.library.basics.core.stathelpers.aliasmethod;
|
||||||
|
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.AliasSamplerDoubleInt;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.AliasSamplerDoubleLong;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.EvProbD;
|
||||||
|
import io.nosqlbench.virtdata.library.basics.core.stathelpers.EvProbLongDouble;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class AliasSamplerDoubleLongTest {
|
||||||
|
|
||||||
|
private final static Logger logger = LogManager.getLogger(AliasSamplerDoubleLongTest.class);
|
||||||
|
@Test
|
||||||
|
public void testAliasSamplerBinaryFractions() {
|
||||||
|
List<EvProbLongDouble> events = new ArrayList();
|
||||||
|
events.add(new EvProbLongDouble(1L,1.0D));
|
||||||
|
events.add(new EvProbLongDouble(2L,1.0D));
|
||||||
|
events.add(new EvProbLongDouble(3L,2.0D));
|
||||||
|
events.add(new EvProbLongDouble(4L,4.0D));
|
||||||
|
events.add(new EvProbLongDouble(5L,8.0D));
|
||||||
|
events.add(new EvProbLongDouble(6L,16.0D));
|
||||||
|
events.add(new EvProbLongDouble(7L,32.0D));
|
||||||
|
events.add(new EvProbLongDouble(8L,64.0D));
|
||||||
|
|
||||||
|
AliasSamplerDoubleLong as = new AliasSamplerDoubleLong(events);
|
||||||
|
int[] stats = new int[9];
|
||||||
|
for (int i = 0; i < 10000; i++) {
|
||||||
|
double v = (double)i / 10000D;
|
||||||
|
long idx = as.applyAsLong(v);
|
||||||
|
stats[(int)idx]++;
|
||||||
|
}
|
||||||
|
logger.debug(Arrays.toString(stats));
|
||||||
|
assertThat(stats).containsExactly(0,79,79,157,313,626,1250,2499,4997);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasSamplerSimple() {
|
||||||
|
List<EvProbD> events = new ArrayList<>();
|
||||||
|
events.add(new EvProbD(1,1D));
|
||||||
|
events.add(new EvProbD(2,2D));
|
||||||
|
events.add(new EvProbD(3,3D));
|
||||||
|
|
||||||
|
AliasSamplerDoubleInt as = new AliasSamplerDoubleInt(events);
|
||||||
|
|
||||||
|
int[] stats = new int[4];
|
||||||
|
for (int i = 0; i < 10000; i++) {
|
||||||
|
double v = (double)i / 10000D;
|
||||||
|
int idx = as.applyAsInt(v);
|
||||||
|
stats[idx]++;
|
||||||
|
}
|
||||||
|
logger.debug(Arrays.toString(stats));
|
||||||
|
assertThat(stats).containsExactly(0,1667,3334,4999);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_double;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 org.assertj.core.data.Offset;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.function.LongToDoubleFunction;
|
||||||
|
import java.util.function.LongUnaryOperator;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class HashMixTest {
|
||||||
|
|
||||||
|
private final static LongToDoubleFunction TO_UNIT_INTERVAL =
|
||||||
|
(l) -> ((double) l) / ((double) Long.MAX_VALUE);
|
||||||
|
private final static Object TO_UNIT_INTERVAL_OBJ = (Object) TO_UNIT_INTERVAL;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLinearMix() {
|
||||||
|
DoubleHolder dh = new DoubleHolder();
|
||||||
|
LongHolder lh = new LongHolder();
|
||||||
|
HashMix um1 = new HashMix(TO_UNIT_INTERVAL, TO_UNIT_INTERVAL,dh, lh);
|
||||||
|
for (long i = 0; i >= 0L; i += 1L << 58) {
|
||||||
|
double fraction = TO_UNIT_INTERVAL.applyAsDouble(i);
|
||||||
|
lh.setValue(i);
|
||||||
|
dh.setValue(fraction);
|
||||||
|
double actual = um1.applyAsDouble(i);
|
||||||
|
double expected = TO_UNIT_INTERVAL.applyAsDouble(i);
|
||||||
|
assertThat(actual).isEqualTo(expected, Offset.offset(0.0000001d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCrossfadeMix() {
|
||||||
|
LongToDoubleFunction rampdown1 = l -> 1.0d - TO_UNIT_INTERVAL.applyAsDouble(l);
|
||||||
|
LongToDoubleFunction rampdown2 = l -> 2.0d - TO_UNIT_INTERVAL.applyAsDouble(l);
|
||||||
|
HashMix um1 = new HashMix(rampdown1, rampdown2);
|
||||||
|
for (long i = 0; i >= 0L; i += 1L << 58) {
|
||||||
|
double value = um1.applyAsDouble(i);
|
||||||
|
assertThat(um1.applyAsDouble(i)).isEqualTo(1.0d, Offset.offset(0.0000001d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DoubleHolder implements LongToDoubleFunction {
|
||||||
|
|
||||||
|
private double value;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double applyAsDouble(long value) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(double value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LongHolder implements LongUnaryOperator {
|
||||||
|
private long value;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long applyAsLong(long operand) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(long value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_double;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 org.assertj.core.data.Offset;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class LERPTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleLerp() {
|
||||||
|
assertThat(LERP.lerp(10.0d,10.0d,1.0d)).isEqualTo(10.0d, Offset.offset(0.00001d));
|
||||||
|
assertThat(LERP.lerp(10.0d,0.0d,0.0d)).isEqualTo(10.0d, Offset.offset(0.00001d));
|
||||||
|
assertThat(LERP.lerp(10.0d,0.0d,1.0d)).isEqualTo(0.0d, Offset.offset(0.00001d));
|
||||||
|
assertThat(LERP.lerp(10.0d,5.0d,0.5d)).isEqualTo(7.5d, Offset.offset(0.00001d));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_double;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.virtdata.library.basics.shared.from_double.to_long.UnitHistribution;
|
||||||
|
import org.assertj.core.data.Offset;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
public class UnitHistributionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUniformSyntaxRequired() {
|
||||||
|
assertThatThrownBy(() -> new UnitHistribution("1 2:2 3:3")).hasMessageContaining(
|
||||||
|
"all elements must be");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasicHistribution() {
|
||||||
|
UnitHistribution h = new UnitHistribution("1:1 2:2 3:3");
|
||||||
|
long[] counts = new long[10];
|
||||||
|
int total=1000000;
|
||||||
|
HashRange hr = new HashRange(0.0d, 1.0d);
|
||||||
|
for (int i = 0; i < total; i++) {
|
||||||
|
double hash = hr.applyAsDouble(i);
|
||||||
|
long v = h.applyAsLong(hash);
|
||||||
|
counts[(int)v]++;
|
||||||
|
}
|
||||||
|
assertThat((double) counts[0] / (double) total).isEqualTo(0.0d, Offset.offset(0.01));
|
||||||
|
assertThat((double) counts[1] / (double) total).isEqualTo(0.16666666d, Offset.offset(0.01));
|
||||||
|
assertThat((double) counts[2] / (double) total).isEqualTo(0.33333333d,
|
||||||
|
Offset.offset(0.01));
|
||||||
|
assertThat((double) counts[3] / (double) total).isEqualTo(0.5d, Offset.offset(0.01));
|
||||||
|
System.out.println(Arrays.toString(counts));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user