1111 * Author : joney_000[ developer.jaswant@gmail.com ]
1212 * Algorithm : Consistent Hashing Circle
1313 * Platform : Generic Distributed Cache Data Nodes, Databases [eg. Memcached ]
14- * Ref : Hash Functions, Fast Data Backups, Distributed Systems
14+ * Ref : Hash Functions, Fast Data Backups, Distributed Systems,
1515 */
1616
1717class ConsistentHashDataNode <T > {
1818 T data ;
1919 public ConsistentHashDataNode (T data ){
2020 this .data = data ;
2121 }
22+
23+ @ Override
24+ public boolean equals (Object obj ){
25+ return this .data .equals ((T )obj );
26+ }
27+
28+ @ Override
29+ public int hashCode (){
30+ return this .data .hashCode ();
31+ }
2232}
2333
2434class Server <T > extends ConsistentHashDataNode <T >{
@@ -31,34 +41,55 @@ public Server(String id, String ip, String contry, T serverMetaData){
3141 }
3242}
3343
34- class ConsistentHashing <T > {
44+ class ConsistentHashing <K , V > {
3545
36- private TreeMap <Long , T > circle ;
37- private Map < T , List <String >> nodeListMap ;
46+ private TreeMap <Long , V > circle ;
47+ private HashMap < V , List <String >> nodeListMap ;
3848 private int noOfAliasForEachServer ;
3949
4050 public ConsistentHashing (int noOfAliasForEachServer ){
4151 this .noOfAliasForEachServer = noOfAliasForEachServer ;
42- circle = new TreeMap <Long , T >();
43- nodeListMap = new HashMap <T , List <String >>();
52+ circle = new TreeMap <Long , V >();
53+ nodeListMap = new HashMap <V , List <String >>();
4454 }
4555
46- void put (T key , ConsistentHashDataNode value ){
47-
56+ void put (String key , V value ){
57+ Long hash = getHash (key );
58+ circle .put (hash , value );
4859 }
49-
50- void putAll ( List < ConsistentHashDataNode < T >> dataNodes ){
51- for ( ConsistentHashDataNode < T > dataNode : dataNodes ){
52- // put(server.data, server );
60+
61+ V remove ( String key ){
62+ if ( circle . containsKey ( key ) ){
63+ return circle . remove ( key );
5364 }
65+ return null ;
5466 }
67+
68+ void addServer (K key , V value ){
69+ put (key .toString (), value );
70+ for (int replicaId = 0 ; replicaId < noOfAliasForEachServer ; replicaId ++){
71+ String keyStr = key .toString () + " replica ~ " +replicaId ;
72+ put (keyStr , value );
73+ }
74+ }
75+
76+ void removeServer (K key ){
77+ remove (key .toString ());
78+ for (int replicaId = 0 ; replicaId < noOfAliasForEachServer ; replicaId ++){
79+ String keyStr = key .toString () + " replica ~ " +replicaId ;
80+ remove (keyStr );
81+ }
82+ }
83+
5584 public static void main (String ... args ){
5685 try {
57- ConsistentHashing <ConsistentHashDataNode <String >> cHash = new ConsistentHashing <>(5 );
86+ ConsistentHashing <String , ConsistentHashDataNode <String >> cHash = new ConsistentHashing <>(5 );
5887
5988 List <ConsistentHashDataNode <String >> servers = new LinkedList <>();
6089 for (int i = 0 ; i < 4 ; i ++){
61- servers .add (new Server <String >("server-id-" +i , "109.105.110.5" +i , "India" , "server-metadata : id: " +i +" , region : IN/Asia" ));
90+ ConsistentHashDataNode <String > newServer = new Server <String >("server-id-" +i , "109.105.110.5" +i , "India" , "server-metadata : id: " +i +" , region : IN/Asia" );
91+ servers .add (newServer );
92+ cHash .addServer (newServer .data , newServer ); // Adding new server to circle
6293 }
6394
6495 List <ConsistentHashDataNode <String >> data = new LinkedList <>();
@@ -88,7 +119,7 @@ public static void main(String ... args){
88119 * Credit: MurmurHash from SMHasher written by Austin Appleby
89120 * Ref : https://en.wikipedia.org/wiki/MurmurHash
90121 */
91- public Long hash (String key ){
122+ public Long getHash (String key ){
92123 ByteBuffer buf = ByteBuffer .wrap (key .getBytes ());
93124 int seed = 0x1234ABCD ;
94125 ByteOrder byteOrder = buf .order ();
0 commit comments