#include <iostream>
#include <vector>
#include <string>
#include <ctime> // to initialize random number generator
//#include <cstdlib>
#include <unordered_map>
#include <algorithm>
using namespace std;
typedef struct {
string name;
int weight;
int key; // server key. Used in hashing
} server;
vector< float > testConsistentHashingVirtualServer( vector< server> & serverList, int replica) {
vector< server> replicaList;
int totalWeight = 0 ;
for ( int i = 0 ; i < serverList.size ( ) ; i++ ) {
totalWeight + = serverList[ i] .weight ;
for ( int rep = 0 ; rep < replica* serverList[ i] .weight ; rep++ ) {
server* tmp = new server( ) ;
tmp- > key = rand ( ) % RAND_MAX ;
tmp- > name = serverList[ i] .name ;
tmp- > weight = 1 ;
replicaList.push_back ( * tmp) ;
}
}
sort( replicaList.begin ( ) , replicaList.end ( ) , [ ] ( server a, server b) { return a.key < b.key ; } ) ;
unordered_map< string, float > um;
for ( int i = 0 ; i < replicaList.size ( ) ; i++ ) {
if ( i == 0 ) um[ replicaList[ 0 ] .name ] = replicaList[ 0 ] .key + 1 ;
else {
um[ replicaList[ i] .name ] + = replicaList[ i] .key - replicaList[ i - 1 ] .key ;
}
}
um[ replicaList[ 0 ] .name ] + = RAND_MAX - 1 - replicaList.back ( ) .key ;
vector< float > ret;
for ( int i = 0 ; i < serverList.size ( ) ; i++ ) {
ret.push_back ( ( ( float ) um[ serverList[ i] .name ] ) / RAND_MAX * totalWeight) ;
}
return ret;
}
int main( ) {
srand ( time ( 0 ) ) ;
// We simulate 7 servers. Each with different weight (INT value)
server s[ ] = { { "a" , 1 , 0 } , { "b" , 3 , 0 } , { "c" , 2 , 0 } , \
{ "d" , 4 , 0 } , { "e" , 6 , 0 } , { "f" , 8 , 0 } , \
{ "g" , 1 , 0 } } ;
vector< server> vs;
for ( int i = 0 ; i < sizeof ( s) / sizeof ( s[ 0 ] ) ; i++ ) vs.push_back ( s[ i] ) ;
// and each server is mapped to 400 replica. In total we simulate 2800 virtual servers.
auto ret = testConsistentHashingVirtualServer( vs, 400 ) ;
for ( int i = 0 ; i < sizeof ( s) / sizeof ( s[ 0 ] ) ; i++ ) {
cout << "Server " << s[ i] .name << " has weight " << s[ i] .weight \
<< " and is now occuping " << ret[ i] << " of all hashing space." << endl;
}
return EXIT_SUCCESS ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8Y3RpbWU+CS8vIHRvIGluaXRpYWxpemUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IKLy8jaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxhbGdvcml0aG0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIHN0cnVjdCB7CglzdHJpbmcgbmFtZTsKCWludCB3ZWlnaHQ7CglpbnQga2V5OwkvLyBzZXJ2ZXIga2V5LiBVc2VkIGluIGhhc2hpbmcKfSBzZXJ2ZXI7Cgp2ZWN0b3I8ZmxvYXQ+IHRlc3RDb25zaXN0ZW50SGFzaGluZ1ZpcnR1YWxTZXJ2ZXIodmVjdG9yPHNlcnZlcj4gJnNlcnZlckxpc3QsIGludCByZXBsaWNhKSB7Cgl2ZWN0b3I8c2VydmVyPiByZXBsaWNhTGlzdDsKCWludCB0b3RhbFdlaWdodCA9IDA7Cglmb3IgKGludCBpID0gMDsgaSA8IHNlcnZlckxpc3Quc2l6ZSgpOyBpKyspIHsKCQl0b3RhbFdlaWdodCArPSBzZXJ2ZXJMaXN0W2ldLndlaWdodDsKCQlmb3IgKGludCByZXAgPSAwOyByZXAgPCByZXBsaWNhKnNlcnZlckxpc3RbaV0ud2VpZ2h0OyByZXArKykgewoJCQlzZXJ2ZXIqIHRtcCA9IG5ldyBzZXJ2ZXIoKTsKCQkJdG1wLT5rZXkgPSByYW5kKCkgJSBSQU5EX01BWDsKCQkJdG1wLT5uYW1lID0gc2VydmVyTGlzdFtpXS5uYW1lOwoJCQl0bXAtPndlaWdodCA9IDE7CgkJCXJlcGxpY2FMaXN0LnB1c2hfYmFjaygqdG1wKTsKCQl9Cgl9Cglzb3J0KHJlcGxpY2FMaXN0LmJlZ2luKCksIHJlcGxpY2FMaXN0LmVuZCgpLCBbXShzZXJ2ZXIgYSwgc2VydmVyIGIpe3JldHVybiBhLmtleSA8IGIua2V5OyB9KTsKCXVub3JkZXJlZF9tYXA8c3RyaW5nLCBmbG9hdD4gdW07Cglmb3IgKGludCBpID0gMDsgaSA8IHJlcGxpY2FMaXN0LnNpemUoKTsgaSsrKSB7CgkJaWYgKGkgPT0gMCkgdW1bcmVwbGljYUxpc3RbMF0ubmFtZV0gPSByZXBsaWNhTGlzdFswXS5rZXkrMTsKCQllbHNlIHsKCQkJdW1bcmVwbGljYUxpc3RbaV0ubmFtZV0gKz0gcmVwbGljYUxpc3RbaV0ua2V5IC0gcmVwbGljYUxpc3RbaSAtIDFdLmtleTsKCQl9Cgl9Cgl1bVtyZXBsaWNhTGlzdFswXS5uYW1lXSArPSBSQU5EX01BWCAtIDEgLSByZXBsaWNhTGlzdC5iYWNrKCkua2V5OwoJdmVjdG9yPGZsb2F0PiByZXQ7Cglmb3IgKGludCBpID0gMDsgaSA8IHNlcnZlckxpc3Quc2l6ZSgpOyBpKyspIHsKCQlyZXQucHVzaF9iYWNrKCgoZmxvYXQpdW1bc2VydmVyTGlzdFtpXS5uYW1lXSkgLyBSQU5EX01BWCAqIHRvdGFsV2VpZ2h0KTsKCX0KCXJldHVybiByZXQ7Cn0KCmludCBtYWluKCkgewoJc3JhbmQodGltZSgwKSk7CgkvLyBXZSBzaW11bGF0ZSA3IHNlcnZlcnMuIEVhY2ggd2l0aCBkaWZmZXJlbnQgd2VpZ2h0IChJTlQgdmFsdWUpCglzZXJ2ZXIgc1tdID0geyB7ICJhIiwgMSwgMCB9LCB7ICJiIiwgMywgMCB9LCB7ICJjIiwgMiwgMCB9LCBcCgkgICAgICAgICAgICAgICB7ICJkIiwgNCwgMCB9LCB7ICJlIiwgNiwgMCB9LCB7ICJmIiwgOCwgMCB9LCBcCgkgICAgICAgICAgICAgICB7ICJnIiwgMSwgMCB9IH07Cgl2ZWN0b3I8c2VydmVyPiB2czsKCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZW9mKHMpIC8gc2l6ZW9mKHNbMF0pOyBpKyspIHZzLnB1c2hfYmFjayhzW2ldKTsKCS8vIGFuZCBlYWNoIHNlcnZlciBpcyBtYXBwZWQgdG8gNDAwIHJlcGxpY2EuIEluIHRvdGFsIHdlIHNpbXVsYXRlIDI4MDAgdmlydHVhbCBzZXJ2ZXJzLgoJYXV0byByZXQgPSB0ZXN0Q29uc2lzdGVudEhhc2hpbmdWaXJ0dWFsU2VydmVyKHZzLCA0MDApOwoJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplb2YocykgLyBzaXplb2Yoc1swXSk7IGkrKykgewoJCWNvdXQgPDwgIlNlcnZlciAiIDw8IHNbaV0ubmFtZSA8PCAiIGhhcyB3ZWlnaHQgIiA8PCBzW2ldLndlaWdodCBcCgkJCSA8PCAiIGFuZCBpcyBub3cgb2NjdXBpbmcgIiA8PCByZXRbaV0gPDwgIiBvZiBhbGwgaGFzaGluZyBzcGFjZS4iIDw8IGVuZGw7Cgl9CgoJcmV0dXJuIEVYSVRfU1VDQ0VTUzsKfQ==