All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bdware.doip.cluster.util.RouteUtil Maven / Gradle / Ivy

There is a newer version: 1.5.4
Show newest version
package org.bdware.doip.cluster.util;

public class RouteUtil {

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

    private double md5Double(String string) {
        int intValue = md5Int(string);
        int N = 0x10000;
        return (intValue % N) / (double) N;
    }

    public int locateByStraw(String address, int clusterMemberSize, double[] weights) {
        assert weights.length == clusterMemberSize;
        double maxHash = Double.NEGATIVE_INFINITY;
        int maxi = -1;
        for (int i = 0; i < clusterMemberSize; ++i) {
            double hash = md5Int(address) * weights[i];
            if (hash > maxHash) {
                maxHash = hash;
                maxi = i;
            }
        }
        return maxi;
    }

    public int locateByUniform(String address, int clusterMemberSize, double[] weights) {
        assert weights.length == clusterMemberSize;
        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 < (double) 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');
        TreeNode thisNode = new TreeNode(label.toString(), leftTree.weight + rightTree.weight, level,
                leftTree.leafCount + rightTree.leafCount);
        thisNode.leftChild = leftTree;
        thisNode.rightChild = rightTree;
        return thisNode;
    }

    private int log2(int n) {
        if (n < 1)
            return -1;
        int x = 1, i = 0;
        for (; x < n; ++i)
            x *= 2;
        return i;
    }

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

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy