Skip to content

Commit 552b5b0

Browse files
committed
add consistent hashing for distributed cache
1 parent 72f081b commit 552b5b0

File tree

1 file changed

+77
-88
lines changed

1 file changed

+77
-88
lines changed

Concurrency/ConsistentHashing.java

Lines changed: 77 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import java.util.HashMap;
55
import java.util.List;
66
import java.util.LinkedList;
7-
87
import java.nio.ByteBuffer;
98
import java.nio.ByteOrder;
9+
1010
/**
1111
* Author : joney_000[ [email protected] ]
1212
* Algorithm : Consistent Hashing Circle
@@ -43,27 +43,27 @@ public Server(String id, String ip, String contry, T serverMetaData){
4343

4444
class ConsistentHashing <K, V> {
4545

46-
private TreeMap<Long, V> circle;
47-
private HashMap<V, List<String>> nodeListMap;
48-
private int noOfAliasForEachServer;
46+
private TreeMap<Long, V> circle;
47+
private HashMap<V, List<String>> nodeListMap;
48+
private int noOfAliasForEachServer;
4949

50-
public ConsistentHashing(int noOfAliasForEachServer){
51-
this.noOfAliasForEachServer = noOfAliasForEachServer;
52-
circle = new TreeMap<Long, V>();
53-
nodeListMap = new HashMap<V, List<String>>();
54-
}
50+
public ConsistentHashing(int noOfAliasForEachServer){
51+
this.noOfAliasForEachServer = noOfAliasForEachServer;
52+
circle = new TreeMap<Long, V>();
53+
nodeListMap = new HashMap<V, List<String>>();
54+
}
5555

56-
void put(String key, V value){
57-
Long hash = getHash(key);
58-
circle.put(hash, value);
59-
}
60-
61-
V remove(String key){
62-
if(circle.containsKey(key)){
63-
return circle.remove(key);
64-
}
65-
return null;
66-
}
56+
void put(String key, V value){
57+
Long hash = getHash(key);
58+
circle.put(hash, value);
59+
}
60+
61+
V remove(String key){
62+
if(circle.containsKey(key)){
63+
return circle.remove(key);
64+
}
65+
return null;
66+
}
6767

6868
void addServer(K key, V value){
6969
put(key.toString(), value);
@@ -74,91 +74,80 @@ void addServer(K key, V value){
7474
}
7575
}
7676

77-
void removeServer(K key){
78-
remove(key.toString());
79-
for(int replicaId = 0; replicaId < noOfAliasForEachServer; replicaId++){
80-
String keyStr = key.toString() + " replica ~ "+replicaId;
81-
remove(keyStr);
82-
}
83-
}
77+
void removeServer(K key){
78+
remove(key.toString());
79+
for(int replicaId = 0; replicaId < noOfAliasForEachServer; replicaId++){
80+
String keyStr = key.toString() + " replica ~ "+replicaId;
81+
remove(keyStr);
82+
}
83+
}
8484

85-
public V getServerNode(String val) {
86-
Long hashing = getHash(val);
87-
SortedMap<Long, V> tail = circle.tailMap(hashing);
88-
return circle.get(tail.size() == 0 ? circle.firstKey() : tail.firstKey());
89-
}
85+
V getServerNode(String val) {
86+
Long hashing = getHash(val);
87+
SortedMap<Long, V> tail = circle.tailMap(hashing);
88+
return circle.get(tail.size() == 0 ? circle.firstKey() : tail.firstKey());
89+
}
9090

9191
public static void main(String ... args){
9292
try{
9393
ConsistentHashing<String, ConsistentHashDataNode<String>> cHash = new ConsistentHashing<>(5);
94-
9594
List <ConsistentHashDataNode<String>> servers = new LinkedList<>();
96-
for(int i = 0; i < 4; i++){
97-
ConsistentHashDataNode<String> newServer = new Server<String>("server-id-"+i, "109.105.110.5"+i, "India", "server-metadata : id: "+i+" , region : IN/Asia");
95+
96+
for(int serverId = 0; serverId < 4; serverId++){
97+
ConsistentHashDataNode<String> newServer = new Server<String>("server-id-"+serverId,
98+
"109.105.110.5" + serverId,
99+
"India",
100+
"server-metadata : id = " + serverId + ", region : IN/Asia");
98101
servers.add(newServer);
99102
cHash.addServer(newServer.data, newServer); // Adding new server to circle
100103
}
101104

102105
List <ConsistentHashDataNode<String>> data = new LinkedList<>();
103-
for(int i = 0; i < 50; i++){
104-
data.add(new ConsistentHashDataNode<String>("data-node-"+i));
106+
for(int dataNodeId = 0; dataNodeId < 50; dataNodeId++){
107+
data.add(new ConsistentHashDataNode<String>("data-node-"+dataNodeId));
105108
}
106-
107-
108-
109109

110110
}catch(RuntimeException ex){
111-
System.err.println("Runtime Exception Stacktrace: " + ex.toString());
111+
System.err.println("Computing Failed Stacktrace: " + ex.toString());
112112
}
113113
}
114-
115-
116-
117-
118-
119-
120114

121-
122-
123-
124-
125-
/**
126-
* Credit: MurmurHash from SMHasher written by Austin Appleby
127-
* Ref : https://en.wikipedia.org/wiki/MurmurHash
128-
*/
129-
public Long getHash(String key){
130-
ByteBuffer buf = ByteBuffer.wrap(key.getBytes());
131-
int seed = 0x1234ABCD;
132-
ByteOrder byteOrder = buf.order();
133-
buf.order(ByteOrder.LITTLE_ENDIAN);
134-
long m = 0xc6a4a7935bd1e995L;
135-
int r = 47;
136-
long h = seed ^ (buf.remaining() * m);
137-
long k;
138-
while(buf.remaining() >= 8){
139-
k = buf.getLong();
140-
k *= m;
141-
k ^= k >>> r;
142-
k *= m;
143-
144-
h ^= k;
145-
h *= m;
146-
}
147-
if(buf.remaining() > 0){
148-
ByteBuffer finish = ByteBuffer.allocate(8).order(
149-
ByteOrder.LITTLE_ENDIAN);
150-
// for big-endian version, do this first:
151-
// finish.position(8-buf.remaining());
152-
finish.put(buf).rewind();
153-
h ^= finish.getLong();
154-
h *= m;
155-
}
156-
h ^= h >>> r;
157-
h *= m;
158-
h ^= h >>> r;
159-
buf.order(byteOrder);
160-
return h;
161-
}
115+
/**
116+
* Credit: MurmurHash from SMHasher written by Austin Appleby
117+
* Ref : https://en.wikipedia.org/wiki/MurmurHash
118+
*/
119+
public Long getHash(String key){
120+
ByteBuffer buf = ByteBuffer.wrap(key.getBytes());
121+
int seed = 0x1234ABCD;
122+
ByteOrder byteOrder = buf.order();
123+
buf.order(ByteOrder.LITTLE_ENDIAN);
124+
long m = 0xc6a4a7935bd1e995L;
125+
int r = 47;
126+
long h = seed ^ (buf.remaining() * m);
127+
long k;
128+
while(buf.remaining() >= 8){
129+
k = buf.getLong();
130+
k *= m;
131+
k ^= k >>> r;
132+
k *= m;
133+
h ^= k;
134+
h *= m;
135+
}
136+
if(buf.remaining() > 0){
137+
ByteBuffer finish = ByteBuffer.allocate(8).order(
138+
ByteOrder.LITTLE_ENDIAN);
139+
// for big-endian version, do this first:
140+
// finish.position(8-buf.remaining());
141+
finish.put(buf).rewind();
142+
h ^= finish.getLong();
143+
h *= m;
144+
}
145+
h ^= h >>> r;
146+
h *= m;
147+
h ^= h >>> r;
148+
buf.order(byteOrder);
149+
return h;
150+
}
162151
}
163152

164153

0 commit comments

Comments
 (0)