* @Author hxchen
* @Date 2020/7/8
*/
public class NodeCircle {
public static void main(String[] args) {
final int serverCount = 10;
final int eachServerNodeCount = 1000;
List<Server> serverList = new ArrayList<>();
for (int i = 0; i < serverCount; i++) {
serverList.add(new Server(i, eachServerNodeCount));
}
List<VirtualNode> circleOrderedVirtualNodes = new ArrayList<>();
serverList.forEach(server -> circleOrderedVirtualNodes.addAll(server.getVirtualNodes()));
long[] arr = circleOrderedVirtualNodes.stream().map(VirtualNode::getCircleIndex)
.sorted(Long::compareTo).mapToLong(Long::longValue).toArray();
circleOrderedVirtualNodes.sort(Comparator.comparing(virtualNode -> virtualNode.circleIndex));
final int keyValueCount = 100_0000;
for (int i = 0; i < keyValueCount; i++) {
long key = new Random().nextLong() & 0xffffffffL;
int keyIndex = getIndex(key, arr);
VirtualNode node = circleOrderedVirtualNodes.get(keyIndex);
node.setHitCount(node.hitCount + 1);
}
System.out.println("标准差为:" + new StandardDeviation().getStandardDeviation(serverList, keyValueCount));
}
static int getIndex(long key, long[] a) {
if (key > a[a.length - 1] || key < a[0]) {
return 0;
}
return bsearch(a, key);
}
static int bsearch(long a[], long key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] > key)
high = mid - 1;
else if (a[mid] < key)
low = mid + 1;
else
return mid;
}
return low;
}
}
class Server {
int serverIndex;
int allHit;
List<VirtualNode> virtualNodes = new ArrayList<>();
public Server(int serverIndex, int virtualNodesCount) {
this.serverIndex = serverIndex;
for (int i = 0; i < virtualNodesCount; i++) {
virtualNodes.add(new VirtualNode(i, new Random().nextLong() & 0xffffffffL));
}
virtualNodes.sort(Comparator.comparing(VirtualNode::getCircleIndex));
}
public void printHit() {
System.out.println("++++++++++++++++++++++++");
System.out.println("++++++++++++++"+ "server" + serverIndex + " hit:" + getAllHit() + "次" + "++++++++++++++");
System.out.println("");
}
public List<VirtualNode> getVirtualNodes() {
return virtualNodes;
}
public int getServerIndex() {
return serverIndex;
}
public int getAllHit() {
return virtualNodes.stream().mapToInt(VirtualNode::getHitCount).sum();
}
public void setAllHit(int allHit) {
this.allHit = allHit;
}
}
class StandardDeviation {
public Double getStandardDeviation(List<Server> servers, int allHit) {
int serverSize = servers.size();
int averageHit = allHit / serverSize;
int temp = 0;
System.out.println("平均hit:" + averageHit);
for (Server s : servers) {
s.printHit();
temp += Math.pow(s.getAllHit() - averageHit, 2);
}
Double standardDeviation = Math.sqrt(temp / serverSize);
return standardDeviation;
}
}
class VirtualNode {
int belongServerIndex;
long circleIndex;
int hitCount = 0;
public VirtualNode(int belongServerIndex, long circleIndex) {
this.belongServerIndex = belongServerIndex;
this.circleIndex = circleIndex;
}
public int getBelongServerIndex() {
return belongServerIndex;
}
public long getCircleIndex() {
return circleIndex;
}
public void setHitCount(int hitCount) {
this.hitCount = hitCount;
}
public int getHitCount() {
return hitCount;
}
public void setIndex(long index) {
if (index == (2 ^ 32)) {
throw new ArrayIndexOutOfBoundsException("数组下标最大为2^32 -1");
}
this.circleIndex = index;
}
}
评论