org.bdware.doip.cluster.engine.DigestUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of doip-audit-tool Show documentation
Show all versions of doip-audit-tool Show documentation
doip audit tool developed by bdware
The newest version!
package org.bdware.doip.cluster.engine;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;
public class DigestUtil {
SecureRandom random = new SecureRandom();
public int nextInt(int n) {
return random.nextInt(n);
}
public String md5Hex(String arg) {
return org.apache.commons.codec.digest.DigestUtils.md5Hex(arg);
}
public int md5Int(String string) {
byte[] bytes = org.apache.commons.codec.digest.DigestUtils.md5(string);
return Math.abs(((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16) | ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF));
}
public double md5Double(String string) {
int intValue = md5Int(string);
int N = 0x10000;
return (intValue % N) / (double) N;
}
public int[] locateByStraw(String address, int clusterMemberSize, int number, double[] weights) {
assert weights.length == clusterMemberSize;
int[] result = new int[number];
PriorityQueue priorityQueue = new PriorityQueue<>(clusterMemberSize,
Comparator.comparingDouble(o -> o.dValue));
for (int i = 0; i < clusterMemberSize; ++i) {
double hash = md5Int(address + i) * weights[i];
priorityQueue.offer(new DoubleInt(hash, i));
}
for (int i = 0; i < number; ++i)
result[i] = priorityQueue.poll().iValue;
return result;
}
public int[] locateByUniform(String address, int clusterMemberSize, int number, double[] weights) {
assert weights.length == clusterMemberSize && number <= clusterMemberSize;
Set integerSet = new HashSet<>();
int[] result = new int[number];
int index = 0;
for (int i = 0; i < number; ++i) {
int retries = 0;
do {
if (++retries > 10) {
for (int j = 0; j < clusterMemberSize; ++j) {
if (!integerSet.contains(j)) {
index = j;
break;
}
}
break;
}
else {
index = locateByUniform(address + (i * 10 + retries), clusterMemberSize, weights);
}
} while (integerSet.contains(index));
integerSet.add(index);
result[i] = index;
}
return result;
}
private int locateByUniform(String address, int clusterMemberSize, double[] weights) {
double totalWeight = 0.0;
for (int i = 0; i < clusterMemberSize; ++i)
totalWeight += weights[i];
double hash = md5Double(address) * totalWeight;
int index = weights.length;
while (hash <= totalWeight)
totalWeight -= weights[--index];
return index;
}
public int locateByTree(String address, int clusterMemberSize, double[] weights) {
assert weights.length == clusterMemberSize;
TreeNode treeNode = createTree(weights);
int index = 0;
while (treeNode.level != 0) {
double hash = md5Double(address + treeNode.label);
if (hash < treeNode.leftChild.weight / treeNode.weight) {
treeNode = treeNode.leftChild;
} else {
treeNode = treeNode.rightChild;
index += treeNode.leftChild.leafCount;
}
}
return index;
}
private TreeNode createTree(double[] weights) {
int length = weights.length;
return createTree("", log2(length), weights, 0, length - 1);
}
private TreeNode createTree(String labelPrefix, int level, double[] weights, int left, int right) {
int size = right - left + 1;
if (size < 1 || level < 0)
return null;
if (level == 0)
return new TreeNode(labelPrefix + '1', weights[left], level, 1);
int x = pow2(level);
int leftSize = Math.min(x / 2, size);
TreeNode leftTree = createTree("", level - 1, weights, left, left + leftSize - 1);
TreeNode rightTree = createTree("1", level - 1, weights, left + leftSize - 1, right);
StringBuilder label = new StringBuilder(labelPrefix);
label.append('1');
for (int i = 0; i < level; ++i)
label.append('0');
assert leftTree != null && rightTree != null;
TreeNode thisNode = new TreeNode(label.toString(), leftTree.weight + rightTree.weight, level,
leftTree.leafCount + rightTree.leafCount);
thisNode.leftChild = leftTree;
thisNode.rightChild = rightTree;
return thisNode;
}
public int log2(int n) {
if (n < 1)
return -1;
int x = 1, i = 0;
for (; x < n; ++i)
x *= 2;
return i;
}
// O(n), can be optimized to O(log(n))
public int pow2(int n) {
if (n < 0)
return -1;
int x = 1;
while (--n >= 0)
x *= 2;
return x;
}
private static class TreeNode {
TreeNode leftChild;
TreeNode rightChild;
String label;
double weight;
int level;
int leafCount;
TreeNode(String label, double weight, int level, int leafCount) {
this.label = label;
this.weight = weight;
this.level = level;
this.leafCount = leafCount;
}
}
private static class DoubleInt {
double dValue;
int iValue;
DoubleInt(double dValue, int iValue) {
this.dValue = dValue;
this.iValue = iValue;
}
}
}