forked from TrueCloudLab/frostfs-sdk-java
parent
c2d70c4f3e
commit
6546e98cf6
49 changed files with 2630 additions and 24 deletions
123
client/src/main/java/info/frostfs/sdk/placement/Tools.java
Normal file
123
client/src/main/java/info/frostfs/sdk/placement/Tools.java
Normal file
|
@ -0,0 +1,123 @@
|
|||
package info.frostfs.sdk.placement;
|
||||
|
||||
import info.frostfs.sdk.dto.netmap.Hasher;
|
||||
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static info.frostfs.sdk.constants.AppConst.UNSIGNED_LONG_MASK;
|
||||
import static info.frostfs.sdk.constants.CryptoConst.*;
|
||||
|
||||
public final class Tools {
|
||||
private Tools() {
|
||||
}
|
||||
|
||||
public static long distance(long x, long y) {
|
||||
long acc = x ^ y;
|
||||
acc ^= acc >>> MURMUR_MULTIPLIER;
|
||||
acc *= LANDAU_PRIME_DIVISOR_65BIT;
|
||||
acc ^= acc >>> MURMUR_MULTIPLIER;
|
||||
acc *= LANDAU_PRIME_DIVISOR_64BIT;
|
||||
acc ^= acc >>> MURMUR_MULTIPLIER;
|
||||
return acc;
|
||||
}
|
||||
|
||||
public static void appendWeightsTo(NodeInfo[] nodes, Function<NodeInfo, Double> wf, double[] weights) {
|
||||
if (weights.length < nodes.length) {
|
||||
weights = new double[nodes.length];
|
||||
}
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
weights[i] = wf.apply(nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends Hasher> List<T> sortHasherSliceByWeightValue(List<T> nodes, double[] weights, long hash) {
|
||||
if (nodes.isEmpty()) {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
boolean allEquals = true;
|
||||
if (weights.length > 1) {
|
||||
for (int i = 1; i < weights.length; i++) {
|
||||
if (weights[i] != weights[0]) {
|
||||
allEquals = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Double[] dist = new Double[nodes.size()];
|
||||
|
||||
if (allEquals) {
|
||||
for (int i = 0; i < dist.length; i++) {
|
||||
long x = nodes.get(i).getHash();
|
||||
dist[i] = toUnsignedBigInteger(distance(x, hash)).doubleValue();
|
||||
}
|
||||
return sortHasherByDistance(nodes, dist, true);
|
||||
}
|
||||
|
||||
for (int i = 0; i < dist.length; i++) {
|
||||
var reverse = UNSIGNED_LONG_MASK.subtract(toUnsignedBigInteger(distance(nodes.get(i).getHash(), hash)));
|
||||
dist[i] = reverse.doubleValue() * weights[i];
|
||||
}
|
||||
|
||||
return sortHasherByDistance(nodes, dist, false);
|
||||
}
|
||||
|
||||
public static <T extends Hasher, N extends Comparable<N>> List<T> sortHasherByDistance(
|
||||
List<T> nodes, N[] dist, boolean asc
|
||||
) {
|
||||
IndexedValue<T, N>[] indexes = new IndexedValue[nodes.size()];
|
||||
for (int i = 0; i < dist.length; i++) {
|
||||
indexes[i] = new IndexedValue<>(nodes.get(i), dist[i]);
|
||||
}
|
||||
|
||||
if (asc) {
|
||||
Arrays.sort(indexes, Comparator.comparing(iv -> iv.dist));
|
||||
} else {
|
||||
Arrays.sort(indexes, (iv1, iv2) -> iv2.dist.compareTo(iv1.dist));
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<>();
|
||||
for (IndexedValue<T, N> iv : indexes) {
|
||||
result.add(iv.nodeInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Function<NodeInfo, Double> defaultWeightFunc(List<NodeInfo> nodes) {
|
||||
MeanAgg mean = new MeanAgg();
|
||||
MinAgg minV = new MinAgg();
|
||||
|
||||
for (NodeInfo node : nodes) {
|
||||
mean.add(node.getCapacity());
|
||||
minV.add(node.getPrice());
|
||||
}
|
||||
|
||||
return newWeightFunc(new SigmoidNorm(mean.compute()), new ReverseMinNorm(minV.compute()));
|
||||
}
|
||||
|
||||
private static BigInteger toUnsignedBigInteger(long i) {
|
||||
return i >= 0 ? BigInteger.valueOf(i) : BigInteger.valueOf(i).and(UNSIGNED_LONG_MASK);
|
||||
}
|
||||
|
||||
private static Function<NodeInfo, Double> newWeightFunc(Normalizer capNorm, Normalizer priceNorm) {
|
||||
return nodeInfo -> capNorm.normalize(nodeInfo.getCapacity().doubleValue())
|
||||
* priceNorm.normalize(nodeInfo.getPrice().doubleValue());
|
||||
}
|
||||
|
||||
private static class IndexedValue<T, N> {
|
||||
final T nodeInfo;
|
||||
final N dist;
|
||||
|
||||
IndexedValue(T nodeInfo, N dist) {
|
||||
this.nodeInfo = nodeInfo;
|
||||
this.dist = dist;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue