Merge branch 'main' into dependabot/maven/mvn-defaults/io.netty-netty-handler-4.1.118.Final

This commit is contained in:
Jonathan Shook 2025-02-19 06:21:56 -06:00 committed by GitHub
commit 3458a8eac1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 1154 additions and 145 deletions

View File

@ -178,17 +178,17 @@
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>java-driver-core</artifactId>
<version>4.18.1</version>
<version>4.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>4.18.1</version>
<version>4.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>java-driver-mapper-runtime</artifactId>
<version>4.18.1</version>
<version>4.19.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>

View File

@ -59,13 +59,11 @@
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>java-driver-core</artifactId>
<version>4.18.1</version>
</dependency>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>4.18.1</version>
</dependency>
<dependency>

View File

@ -28,33 +28,35 @@ import java.util.List;
import java.util.function.Function;
/**
* Normalize a vector in List<Number> form, calling the appropriate conversion function
* depending on the component (Class) type of the incoming List values.
*/
Normalize a vector in List<Number> form, calling the appropriate conversion function
depending on the component (Class) type of the incoming List values. */
@ThreadSafeMapper
@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 NormalizeFloatListVector nfv = new NormalizeFloatListVector();
@Override
public CqlVector apply(CqlVector cqlVector) {
public CqlVector apply(CqlVector<N> cqlVector) {
double[] vals = new double[cqlVector.size()];
double accumulator= 0.0d;
double accumulator = 0.0d;
for (int i = 0; i < vals.length; i++) {
vals[i]=cqlVector.get(i).doubleValue();
accumulator+=vals[i]*vals[i];
vals[i] = cqlVector.get(i).doubleValue();
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) {
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);
} 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);
} 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");
}
}
}

View File

@ -46,9 +46,9 @@ public class NormalizeCqlVectorTest {
@Test
public void normalizeCqlVectorDoubles() {
CqlVector square = CqlVector.newInstance(1.0d, 1.0d);
CqlVector<Number> square = CqlVector.newInstance(1.0d, 1.0d);
NormalizeCqlVector nv = new NormalizeCqlVector();
CqlVector normaled = nv.apply(square);
CqlVector<Number> normaled = nv.apply(square);
assertThat(normaled.size()).isEqualTo(2);
assertThat(normaled.get(0)).isInstanceOf(Double.class);

View File

@ -118,10 +118,10 @@ public class StandardActivity<R extends java.util.function.LongFunction, S> exte
} else {
adapter = adapters.get(driverName);
}
if (adapter instanceof NBConfigurable configurable) {
adapterModel = configurable.getConfigModel();
adapterModel.assertValidConfig(ot.getParams());
}
// if (adapter instanceof NBConfigurable configurable) {
// adapterModel = configurable.getConfigModel();
// adapterModel.assertValidConfig(ot.getParams());
// }
paramsAdvisor.validateAll(ot.getParams().keySet());
paramsAdvisor.validateAll(ot.getTags().keySet());
paramsAdvisor.validateAll(ot.getBindings().keySet());

View File

@ -35,6 +35,7 @@ public class VirtDataFunctions {
LongUnaryOperator(java.util.function.LongUnaryOperator.class, long.class),
IntFunction(java.util.function.IntFunction.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),
DoubleFunction(java.util.function.DoubleFunction.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.
*
* @param func The original function object.
* @param type The type of function object needed.
* @param output The output type required for the adapted function.
* @param truncate 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
Adapt a functional object into a different type of functional object.
@param func
The original function object.
@param type
The type of function object needed.
@param output
The output type required for the adapted function.
@param truncate
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) {
FuncType funcType = FuncType.valueOf(type);
switch (funcType) {
case DoubleToLongFunction:
return truncate ? (F) adaptDoubleToLongFunction(func, output) :
(F) adaptDoubleToLongFunctionStrict(func, output);
case LongUnaryOperator:
return truncate ? (F) adaptLongUnaryOperator(func, output) : (F) adaptLongUnaryOperatorStrict(func, output);
return truncate ? (F) adaptLongUnaryOperator(func, output) :
(F) adaptLongUnaryOperatorStrict(func, output);
case DoubleUnaryOperator:
return truncate ? (F) adaptDoubleUnaryOperator(func, output) : (F) adaptDoubleUnaryOperatorStrict(func, output);
return truncate ? (F) adaptDoubleUnaryOperator(func, output) :
(F) adaptDoubleUnaryOperatorStrict(func, output);
case IntUnaryOperator:
return truncate ? adaptIntUnaryOperator(func, output) : adaptIntUnaryOperatorStrict(func, output);
return truncate ? adaptIntUnaryOperator(func, output) :
adaptIntUnaryOperatorStrict(func, output);
case DoubleFunction:
return truncate ? adaptDoubleFunction(func, output) : adaptDoubleFunctionStrict(func, output);
return truncate ? adaptDoubleFunction(func, output) :
adaptDoubleFunctionStrict(func, output);
case LongFunction:
return truncate ? (F) adaptLongFunction(func, output) : (F) adaptLongFunctionStrict(func, output);
return truncate ? (F) adaptLongFunction(func, output) :
(F) adaptLongFunctionStrict(func, output);
case LongToDoubleFunction:
return truncate ? (F) adaptLongToDoubleFunction(func, output) : (F) adaptLongToDoubleFunctionStrict(func, output);
return truncate ? (F) adaptLongToDoubleFunction(func, output) :
(F) adaptLongToDoubleFunctionStrict(func, output);
case LongToIntFunction:
return truncate ? (F) adaptLongToIntFunction(func, output) : (F) adaptLongFunctionStrict(func, output);
return truncate ? (F) adaptLongToIntFunction(func, output) :
(F) adaptLongFunctionStrict(func, output);
case IntFunction:
return adaptIntFunction(func, output);
case Function:
return truncate ? (F) adaptFunction(func, output) : adaptFunctionStrict(func, output);
return truncate ? (F) adaptFunction(func, output) :
adaptFunctionStrict(func, output);
default:
throw new RuntimeException("Unable to convert function type '" + funcType + "' (" + func.getClass().getName() +
") to " + type.getName() + (truncate ? " WITH " : " WITHOUT ") + "truncation");
throw new RuntimeException(
"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<>();
for (Object func : funcs) {
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());
switch (isaType) {
case LongToDoubleFunction:
@ -119,62 +148,117 @@ public class VirtDataFunctions {
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
return f2::applyAsInt;
case LongFunction:
LongFunction<Double> f3 = assertTypesAssignable(func, LongFunction.class, double.class);
LongFunction<Double> f3 =
assertTypesAssignable(func, LongFunction.class, double.class);
return f3::apply;
case LongUnaryOperator:
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
return f4::applyAsLong;
case DoubleFunction:
DoubleFunction<Double> f7 = assertTypesAssignable(func, DoubleFunction.class, double.class);
DoubleFunction<Double> f7 =
assertTypesAssignable(func, DoubleFunction.class, double.class);
return f7::apply;
case DoubleUnaryOperator:
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
return f8::applyAsDouble;
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();
case IntFunction:
case IntUnaryOperator:
throwNarrowingError(func, isaType.functionClazz);
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) {
FuncType isaType = FuncType.valueOf(func.getClass());
switch (isaType) {
case LongToDoubleFunction:
LongToDoubleFunction f1 = assertTypesAssignable(func, LongToDoubleFunction.class);
return null;
return assertTypesAssignable(func, LongToDoubleFunction.class);
case LongToIntFunction:
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
return null;
return f2::applyAsInt;
case LongFunction:
LongFunction<Double> f3 = assertTypesAssignable(func, LongFunction.class, double.class);
return null;
LongFunction<Double> f3 =
assertTypesAssignable(func, LongFunction.class, double.class);
return f3::apply;
case LongUnaryOperator:
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
return null;
return f4::applyAsLong;
case IntFunction:
IntFunction<Double> f5 = assertTypesAssignable(func, IntFunction.class, double.class);
return null;
IntFunction<Double> f5 =
assertTypesAssignable(func, IntFunction.class, double.class);
return l -> f5.apply((int) l);
case IntUnaryOperator:
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
return null;
return operand -> f6.applyAsInt((int) operand);
case DoubleFunction:
DoubleFunction<Double> f7 = assertTypesAssignable(func, DoubleFunction.class, double.class);
return null;
DoubleFunction<Double> f7 =
assertTypesAssignable(func, DoubleFunction.class, double.class);
return f7::apply;
case DoubleUnaryOperator:
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
return null;
return f8::applyAsDouble;
case Function:
Function<Double, Double> f9 = assertTypesAssignable(func, Function.class, double.class, double.class);
return null;
Function<Double, Double> f9 =
assertTypesAssignable(func, Function.class, double.class, double.class);
return t -> f9.apply((double) t);
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:
LongUnaryOperator f2 = assertTypesAssignable(func, LongUnaryOperator.class);
return f2::applyAsLong;
case LongToDoubleFunction:
LongToDoubleFunction f7 = assertTypesAssignable(func, LongToDoubleFunction.class);
return f7::applyAsDouble;
case LongToIntFunction:
LongToIntFunction f3 = assertTypesAssignable(func, LongToIntFunction.class);
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:
Function<Long, Long> f7 = assertTypesAssignable(func, Function.class, Long.class);
return (long l) -> f7.apply(l);
Function<Long, Long> f8 = assertTypesAssignable(func, Function.class, Long.class);
return f8::apply;
case DoubleUnaryOperator:
case IntUnaryOperator:
case IntFunction:
default:
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
LongUnaryOperator.class.getName() + " since this would cause a narrowing conversion.");
throw new RuntimeException(
"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) {
case LongFunction:
LongFunction<?> f1 = (LongFunction<?>) func;
Function<Long, ?> rf1 = f1::apply;
return rf1;
return (Function<Long, ?>) f1::apply;
case LongUnaryOperator:
LongUnaryOperator f2 = (LongUnaryOperator) func;
Function<Long, Long> rf2 = f2::applyAsLong;
return rf2;
return (Function<Long, Long>) f2::applyAsLong;
case IntFunction:
IntFunction f3 = (IntFunction) func;
Function<Integer, ?> rf3 = f3::apply;
return rf3;
IntFunction<?> f3 = (IntFunction<?>) func;
return (Function<Integer, ?>) f3::apply;
case IntUnaryOperator:
IntUnaryOperator f4 = (IntUnaryOperator) func;
Function<Integer, ?> rf4 = f4::applyAsInt;
return rf4;
return (Function<Integer, ?>) f4::applyAsInt;
case DoubleFunction:
DoubleFunction f5 = (DoubleFunction) func;
Function<Double, ?> rf5 = f5::apply;
return rf5;
DoubleFunction<?> f5 = (DoubleFunction<?>) func;
return (Function<Double, ?>) f5::apply;
case DoubleUnaryOperator:
DoubleUnaryOperator f6 = (DoubleUnaryOperator) func;
Function<Double, ?> rf6 = f6::applyAsDouble;
return rf6;
return (Function<Double, ?>) f6::applyAsDouble;
case LongToDoubleFunction:
LongToDoubleFunction f10 = (LongToDoubleFunction) func;
return (Function<Long, Double>) f10;
case LongToIntFunction:
LongToIntFunction f7 = (LongToIntFunction) func;
Function<Long, Integer> rf7 = f7::applyAsInt;
case Function:
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:
throw new RuntimeException("Unable to map function:" + func);
}
}
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) {
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) {
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) {
@ -255,7 +368,8 @@ public class VirtDataFunctions {
switch (toFuncType) {
case DoubleFunction:
DoubleFunction<Double> f2 = assertTypesAssignable(func, DoubleFunction.class, double.class);
DoubleFunction<Double> f2 =
assertTypesAssignable(func, DoubleFunction.class, double.class);
return f2::apply;
case LongToDoubleFunction:
LongToDoubleFunction f3 = assertTypesAssignable(func, LongToDoubleFunction.class);
@ -264,13 +378,15 @@ public class VirtDataFunctions {
LongToIntFunction f4 = assertTypesAssignable(func, LongToIntFunction.class);
return l -> f4.applyAsInt((long) l % Long.MAX_VALUE);
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);
case LongUnaryOperator:
LongUnaryOperator f6 = assertTypesAssignable(func, LongUnaryOperator.class);
return l -> f6.applyAsLong((long) l % Long.MAX_VALUE);
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);
case IntUnaryOperator:
IntUnaryOperator f8 = assertTypesAssignable(func, IntUnaryOperator.class);
@ -282,25 +398,31 @@ public class VirtDataFunctions {
DoubleUnaryOperator fA = assertTypesAssignable(func, DoubleUnaryOperator.class);
return fA;
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;
default:
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());
switch (toFuncType) {
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;
case DoubleFunction:
DoubleFunction<Double> f2 = assertTypesAssignable(func, DoubleFunction.class, double.class);
DoubleFunction<Double> f2 =
assertTypesAssignable(func, DoubleFunction.class, double.class);
return f2::apply;
default:
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
DoubleUnaryOperator.class.getName() + " since this would cause a narrowing conversion.");
throw new RuntimeException(
"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);
return o5;
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;
default:
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
LongUnaryOperator.class.getName() + " since this would cause a narrowing conversion.");
throw new RuntimeException(
"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) {
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) {
@ -332,31 +458,36 @@ public class VirtDataFunctions {
switch (isaType) {
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);
case LongToIntFunction:
LongToIntFunction f2 = assertTypesAssignable(func, LongToIntFunction.class);
return f2;
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();
case LongUnaryOperator:
LongUnaryOperator f4 = assertTypesAssignable(func, LongUnaryOperator.class);
return l -> (int) (f4.applyAsLong(l) % Integer.MAX_VALUE);
case IntFunction:
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:
IntUnaryOperator f6 = assertTypesAssignable(func, IntUnaryOperator.class);
return l -> f6.applyAsInt((int) l % Integer.MAX_VALUE);
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;
case DoubleUnaryOperator:
DoubleUnaryOperator f8 = assertTypesAssignable(func, DoubleUnaryOperator.class);
return l -> (int) f8.applyAsDouble(l) % Integer.MAX_VALUE;
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;
default:
throw new IllegalStateException("Unexpected value: " + isaType);
@ -397,29 +528,33 @@ public class VirtDataFunctions {
assertOutputAssignable(f9.applyAsInt(1L), output);
return (long l) -> f9.applyAsInt(l);
default:
throw new RuntimeException("Unable to convert " + func.getClass().getName() + " to a " +
LongUnaryOperator.class.getName());
throw new RuntimeException(
"Unable to convert " + func.getClass().getName() + " to a "
+ LongUnaryOperator.class.getName());
}
}
private static void assertOutputAssignable(Object result, Class<?> clazz) {
if (!ClassUtils.isAssignable(result.getClass(), clazz, true)) {
throw new InvalidParameterException("Unable to assign type of " + result.getClass().getName()
+ " to " + clazz.getName());
throw new InvalidParameterException(
"Unable to assign type of " + result.getClass().getName() + " to "
+ clazz.getName());
}
// if (!clazz.isAssignableFrom(result.getClass())) {
// throw new InvalidParameterException("Unable to assign type of " + result.getClass().getName()
// + " to " + clazz.getName());
// }
// if (!clazz.isAssignableFrom(result.getClass())) {
// throw new InvalidParameterException("Unable to assign type of " + result.getClass().getName()
// + " to " + clazz.getName());
// }
}
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) {
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);
return o2::apply;
case DoubleFunction:
DoubleFunction<Long> o3 = assertTypesAssignable(func, DoubleFunction.class, long.class);
DoubleFunction<Long> o3 =
assertTypesAssignable(func, DoubleFunction.class, long.class);
return o3::apply;
case IntUnaryOperator:
IntUnaryOperator o4 = assertTypesAssignable(func, IntUnaryOperator.class);
@ -446,7 +582,8 @@ public class VirtDataFunctions {
DoubleUnaryOperator o6 = assertTypesAssignable(func, DoubleUnaryOperator.class);
return (long l) -> (long) (o6.applyAsDouble(l) % Long.MAX_VALUE);
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;
case LongToDoubleFunction:
LongToDoubleFunction o8 = assertTypesAssignable(func, LongToDoubleFunction.class);
@ -455,49 +592,60 @@ public class VirtDataFunctions {
LongToIntFunction o9 = assertTypesAssignable(func, LongToIntFunction.class);
return o9::applyAsInt;
}
throw new InvalidParameterException("Unable to convert " + func.getClass().getName() + " to a " +
LongUnaryOperator.class.getName());
throw new InvalidParameterException(
"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
* the wanted type. Further, if the wanted type is a generic type, assert that additional classes are assignable to
* the generic type parameters. Thus, if you want to assign to a generic type from a non-generic type, you must
* qualify the types of values that will be used in those generic parameter positions in declaration order.
*
* <p>This is useful for taking any object and a known type and reifying it as the known type so that it can be
* then used idiomatically with normal type awareness. This scenario occurs when you are accepting an open type for
* 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
Given a base object and a wanted type to convert it to, assert that the type of the base object
is assignable to
the wanted type. Further, if the wanted type is a generic type, assert that additional classes
are assignable to
the generic type parameters. Thus, if you want to assign to a generic type from a non-generic
type, you must
qualify the types of values that will be used in those generic parameter positions in
declaration order.
<p>This is useful for taking any object and a known type and reifying it as the known type so
that it can be
then used idiomatically with normal type awareness. This scenario occurs when you are accepting
an open type for
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(
Object base,
Class<T> wantType,
Class<?>... clazzes) {
private static <T> T assertTypesAssignable(Object base, Class<T> wantType, Class<?>... clazzes)
{
if (!wantType.isAssignableFrom(base.getClass())) {
throw new InvalidParameterException("Unable to assign " + wantType.getName() + " from " +
base.getClass().getName());
throw new InvalidParameterException(
"Unable to assign " + wantType.getName() + " from " + base.getClass().getName());
}
TypeVariable<? extends Class<?>>[] typeParameters = base.getClass().getTypeParameters();
if (typeParameters.length > 0) {
if (clazzes.length != typeParameters.length) {
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++) {
Class<?> from = clazzes[i];
TypeVariable<? extends Class<?>> to = typeParameters[i];
boolean assignableFrom = to.getGenericDeclaration().isAssignableFrom(from);
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.
*
* @param func The source function to convert from
* @param targetClass The target class which was requested
Throw an error indicating a narrowing conversion was attempted for strict conversion.
@param func
The source function to convert from
@param targetClass
The target class which was requested
*/
private static void throwNarrowingError(Object func, Class<?> targetClass) {
throw new BasicError("Converting from " + func.getClass().getName() + " to " + targetClass.getName() +
" is not allowed when strict conversion is requested.");
throw new BasicError(
"Converting from " + func.getClass().getName() + " to " + targetClass.getName()
+ " is not allowed when strict conversion is requested.");
}

View File

@ -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))));
}
};
}

View File

@ -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) {
}

View File

@ -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);
}
}

View File

@ -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;
// }
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}