1
一致性哈希算法实现
发布于: 2020 年 07 月 07 日
该代码来源于github,听了老师的讲解,终于理解了这段代码的意思,也加深了一致性哈希的理解,以前都是看一些文章,看的似懂非懂,只知道个概念,这次看了具体的代码实现,终于理解了。
public interface Node { String getKey();}public class VirtualNode<T extends Node> implements Node { final T physicalNode; final int replicaIndex; public VirtualNode(T physicalNode, int replicaIndex) { this.replicaIndex = replicaIndex; this.physicalNode = physicalNode; } @Override public String getKey() { return physicalNode.getKey() + "-" + replicaIndex; } public boolean isVirtualNodeOf(T pNode) { return physicalNode.getKey().equals(pNode.getKey()); } public T getPhysicalNode() { return physicalNode; }}public interface HashFunction { long hash(String key);}public class ConsistentHashRouter<T extends Node> { private final SortedMap<Long, VirtualNode<T>> ring = new TreeMap<>(); private final HashFunction hashFunction; public ConsistentHashRouter(Collection<T> pNodes, int vNodeCount) { this(pNodes,vNodeCount, new MD5Hash()); } public ConsistentHashRouter(Collection<T> pNodes, int vNodeCount, HashFunction hashFunction) { if (hashFunction == null) { throw new NullPointerException("Hash Function is null"); } this.hashFunction = hashFunction; if (pNodes != null) { for (T pNode : pNodes) { addNode(pNode, vNodeCount); } } } public void addNode(T pNode, int vNodeCount) { if (vNodeCount < 0) throw new IllegalArgumentException("illegal virtual node counts :" + vNodeCount); int existingReplicas = getExistingReplicas(pNode); for (int i = 0; i < vNodeCount; i++) { VirtualNode<T> vNode = new VirtualNode<>(pNode, i + existingReplicas); ring.put(hashFunction.hash(vNode.getKey()), vNode); } } public void removeNode(T pNode) { Iterator<Long> it = ring.keySet().iterator(); while (it.hasNext()) { Long key = it.next(); VirtualNode<T> virtualNode = ring.get(key); if (virtualNode.isVirtualNodeOf(pNode)) { it.remove(); } } } public T routeNode(String objectKey) { if (ring.isEmpty()) { return null; } Long hashVal = hashFunction.hash(objectKey); SortedMap<Long,VirtualNode<T>> tailMap = ring.tailMap(hashVal); Long nodeHashVal = !tailMap.isEmpty() ? tailMap.firstKey() : ring.firstKey(); return ring.get(nodeHashVal).getPhysicalNode(); } private int getExistingReplicas(T pNode) { int replicas = 0; for (VirtualNode<T> vNode : ring.values()) { if (vNode.isVirtualNodeOf(pNode)) { replicas++; } } return replicas; } private static class MD5Hash implements HashFunction { MessageDigest instance; public MD5Hash() { try { instance = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { } } @Override public long hash(String key) { instance.reset(); instance.update(key.getBytes()); byte[] digest = instance.digest(); long h = 0; for (int i = 0; i < 4; i++) { h <<= 8; h |= ((int) digest[i]) & 0xFF; } return h; } }}
老师说的测试方法我还没有理解是什么意思?
划线
评论
复制
发布于: 2020 年 07 月 07 日阅读数: 50
老姜
关注
还未添加个人签名 2017.11.16 加入
还未添加个人简介
评论 (1 条评论)