mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
partial functions work
This commit is contained in:
committed by
jeffbanks
parent
b324c59c11
commit
56b96ec1aa
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2023 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long;
|
||||
|
||||
import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||
import io.nosqlbench.virtdata.api.bindings.VirtDataConversions;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Wrap any function producing a valid numeric value as a float.
|
||||
*/
|
||||
@Categories(Category.conversion)
|
||||
@ThreadSafeMapper
|
||||
public class ToFloat implements LongFunction<Float> {
|
||||
|
||||
private final LongFunction<Float> func;
|
||||
|
||||
ToFloat(Object funcOrValue) {
|
||||
if (funcOrValue instanceof Number number) {
|
||||
final float afloat = number.floatValue();
|
||||
this.func = l -> afloat;
|
||||
} else {
|
||||
this.func = VirtDataConversions.adaptFunction(funcOrValue,LongFunction.class,Float.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float apply(long value) {
|
||||
return func.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_double;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Return a value along an interpolation curve. This allows you to sketch a basic
|
||||
* density curve and describe it simply with just a few values. The number of values
|
||||
* provided determines the resolution of the internal lookup table that is used for
|
||||
* interpolation. The first value is always the 0.0 anchoring point on the unit interval.
|
||||
* The last value is always the 1.0 anchoring point on the unit interval. This means
|
||||
* that in order to subdivide the density curve in an interesting way, you need to provide
|
||||
* a few more values in between them. Providing two values simply provides a uniform
|
||||
* sample between a minimum and maximum value.
|
||||
*
|
||||
* The input range of this function is, as many of the other functions in this library,
|
||||
* based on the valid range of positive long values, between 0L and Long.MAX_VALUE inclusive.
|
||||
* This means that if you want to combine interpolation on this curve with the effect of
|
||||
* pseudo-random sampling, you need to put a hash function ahead of it in the flow.
|
||||
*
|
||||
* Developer Note: This is the canonical implementation of LERPing in NoSQLBench, so is
|
||||
* heavily documented. Any other LERP implementations should borrow directly from this,
|
||||
* embedding by default.
|
||||
*/
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.general})
|
||||
public class Interpolate implements LongToDoubleFunction {
|
||||
|
||||
// How many values we have to pick from
|
||||
private final double resolution;
|
||||
|
||||
// The lookup table
|
||||
private final double[] lut;
|
||||
|
||||
/**
|
||||
* The scale of Long.MAX_VALUE and the unit interval scale factor are pre-combined
|
||||
* here to reduce the number of operations later.
|
||||
*
|
||||
* The LUT size is retained as the number of elements provided (resolution) + 1.
|
||||
* The +1 element serves as the N+1 index for when the unit interval sample is
|
||||
* 1.0. In other words, the maximum value is not a special case, as a duplicate
|
||||
* value is appended to the LUT instead.
|
||||
*
|
||||
* This size is the scale factor from the unit interval to the array index. Since
|
||||
* the input comes in as a long value, it is mapped from [0L, Long.MAX_VALUE] to
|
||||
* [0.0D, 1.0D] by multiplying by (1.0/(double)Long.MAX_VALUE). The long input
|
||||
* value can then be multiplied directly to yield a double in the range of
|
||||
* [0,LUT.length-1], which simplifies all remaining LERP math.
|
||||
*
|
||||
*/
|
||||
private final double scaleToLongInterval;
|
||||
|
||||
|
||||
@Example({"Interpolate(0.0d,100.0d)", "return a uniform double value between 0.0d and 100.0d"})
|
||||
@Example({"Interpolate(0.0d,90.0d,95.0d,98.0d,100.0d)", "return a weighted double value where the first second and third quartiles are 90.0D, 95.0D, and 98.0D"})
|
||||
public Interpolate(double... values) {
|
||||
this.resolution = values.length;
|
||||
double[] doubles = new double[values.length + 1];
|
||||
System.arraycopy(values,0,doubles,0,values.length);
|
||||
doubles[doubles.length - 1] = doubles[doubles.length - 2];
|
||||
this.lut = doubles;
|
||||
this.scaleToLongInterval = (this.resolution - 1) * (1.0d / (double) Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double applyAsDouble(long input) {
|
||||
// scale the input from [0,Long.MAX_VALUE] to [0.0,lut.length-1]
|
||||
double samplePoint = scaleToLongInterval * input;
|
||||
// truncate the sample point to the left index
|
||||
int leftidx = (int) samplePoint;
|
||||
// isolate the fractional component
|
||||
double fractional = samplePoint - leftidx;
|
||||
// take the sum of the left component and right component
|
||||
// scaled by closeness to fractional point within the interval, respectively
|
||||
double sample = (lut[leftidx] * (1.0d - fractional)) + (lut[leftidx + 1] * fractional);
|
||||
return sample;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,19 +20,19 @@ import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.general})
|
||||
public class Mul implements LongToDoubleFunction {
|
||||
private final double factor;
|
||||
public class Mul implements LongFunction<Float> {
|
||||
private final float factor;
|
||||
|
||||
public Mul(double factor) {
|
||||
public Mul(float factor) {
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double applyAsDouble(long value) {
|
||||
public Float apply(long value) {
|
||||
return factor * value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2022 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_float;
|
||||
|
||||
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.LongFunction;
|
||||
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.general})
|
||||
public class FixedValues implements LongFunction<Float> {
|
||||
|
||||
private final float[] fixedValues;
|
||||
|
||||
@Example({"FixedValues(3.0,53.0,73d)", "Yield 3D, 53D, 73D, 3D, 53D, 73D, 3D, ..."})
|
||||
public FixedValues(Object... values) {
|
||||
this.fixedValues = new float[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
Object value = values[i];
|
||||
if (value instanceof Number number) {
|
||||
fixedValues[i]=number.floatValue();
|
||||
} else {
|
||||
throw new RuntimeException("Not a number: " + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float apply(long value) {
|
||||
int index = (int) (value % Integer.MAX_VALUE) % fixedValues.length;
|
||||
return fixedValues[index];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2022 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_float;
|
||||
|
||||
import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||
import io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.Hash;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
/*
|
||||
* <p>This simulates a uniform sample from a range of double values
|
||||
* via long hashing. This function attempts to take a double
|
||||
* unit interval value from a long/long division over the whole
|
||||
* range of long values but via double value types, thus providing
|
||||
* a very linear sample. This means that the range of double
|
||||
* values to be accessed will not fall along all possible doubles,
|
||||
* but will still provide suitable values for ranges close to
|
||||
* high-precision points in the IEEE floating point number line.
|
||||
* This suffices for most reasonable ranges in practice outside
|
||||
* of scientific computing, where large exponents put adjacent
|
||||
* IEEE floating point values much further apart.</p>
|
||||
*
|
||||
* <p>This should be consider the default double range sampling
|
||||
* function for most uses, when the exponent is not needed for
|
||||
* readability.</p>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return a double value within the specified range. This function
|
||||
* uses an intermediate long to arrive at the sampled value before
|
||||
* conversion to double, thus providing a more linear sample at the
|
||||
* expense of some precision at extremely large values.
|
||||
*/
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.general})
|
||||
public class HashedFloatRange implements LongFunction<Float> {
|
||||
|
||||
private final float min;
|
||||
private final float max;
|
||||
private final float interval;
|
||||
private final static float MAX_FLOAT_VIA_LONG = (float) Long.MAX_VALUE;
|
||||
private final Hash hash = new Hash();
|
||||
|
||||
public HashedFloatRange(float min, float max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.interval = max - min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float apply(long value) {
|
||||
long hashed = hash.applyAsLong(value);
|
||||
float unitScale = ((float) hashed) / MAX_FLOAT_VIA_LONG;
|
||||
float valueScaled =interval*unitScale + min;
|
||||
return valueScaled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2022 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_float;
|
||||
|
||||
import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||
import io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.Hash;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
/**
|
||||
* This provides a random sample of a double in a range, without
|
||||
* accounting for the non-uniform distribution of IEEE double representation.
|
||||
* This means that values closer to high-precision areas of the IEEE spec
|
||||
* will be weighted higher in the output. However, NaN and positive and
|
||||
* negative infinity are filtered out via oversampling. Results are still
|
||||
* stable for a given input value.
|
||||
*/
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.general})
|
||||
public class HashedRangedToNonuniformFloat implements LongFunction<Float> {
|
||||
|
||||
private final long min;
|
||||
private final long max;
|
||||
private final float length;
|
||||
private final Hash hash;
|
||||
|
||||
public HashedRangedToNonuniformFloat(long min, long max) {
|
||||
this.hash = new Hash();
|
||||
if (max<=min) {
|
||||
throw new RuntimeException("max must be >= min");
|
||||
}
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.length = (float) max - min;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ":" + min + ":" + max;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Float apply(long input) {
|
||||
long bitImage = hash.applyAsLong(input);
|
||||
double value = Math.abs(Double.longBitsToDouble(bitImage));
|
||||
while (!Double.isFinite(value)) {
|
||||
input++;
|
||||
bitImage = hash.applyAsLong(input);
|
||||
value = Math.abs(Double.longBitsToDouble(bitImage));
|
||||
}
|
||||
value %= length;
|
||||
value += min;
|
||||
float floatValue = (float) value;
|
||||
return floatValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_float;
|
||||
|
||||
import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.general})
|
||||
public class Mul implements LongToDoubleFunction {
|
||||
private final double factor;
|
||||
|
||||
public Mul(double factor) {
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double applyAsDouble(long value) {
|
||||
return factor * value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2022 nosqlbench
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_float;
|
||||
|
||||
import io.nosqlbench.virtdata.api.annotations.Categories;
|
||||
import io.nosqlbench.virtdata.api.annotations.Category;
|
||||
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
|
||||
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
|
||||
/**
|
||||
* Convert the input value to a double.
|
||||
*/
|
||||
@ThreadSafeMapper
|
||||
@Categories({Category.conversion})
|
||||
public class ToDouble implements LongToDoubleFunction {
|
||||
|
||||
@Override
|
||||
public double applyAsDouble(long value) {
|
||||
return (double) value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user