26 #ifndef DOZERG_CONSISTENT_HASH_H_20131127 27 #define DOZERG_CONSISTENT_HASH_H_20131127 33 #include "template.hh" 70 template<
typename>
class HashKey =
CHashFn 77 typedef uint32_t value_type;
78 typedef HashKey<key_type> hasher;
80 typedef std::map<value_type, value_type> __Map;
83 std::vector<value_type> pos_;
84 size_t weight()
const{
return pos_.size();}
86 typedef std::map<value_type, __Node> __Values;
94 value_type
hash(
const key_type & key)
const{
95 assert(!ring_.empty());
96 const value_type h = hasher()(key);
97 typename __Map::const_iterator wh = ring_.lower_bound(h);
107 void setValue(value_type value,
size_t weight = 1000){
109 __Node & n = values_[value];
110 if(n.weight() > weight){
111 removeNode(value, weight, n);
112 }
else if(n.weight() < weight)
113 insertNode(value, weight, n);
115 typename __Values::iterator wh = values_.find(value);
116 if(values_.end() != wh){
117 removeNode(value, 0, wh->second);
125 void actualWeight(std::vector<std::pair<value_type, value_type> > & results)
const{
126 assert(!ring_.empty());
128 for(
typename __Map::const_iterator it = ring_.begin();it != ring_.end();++it){
129 addWeight(it->second, it->first - last, results);
132 addWeight(ring_.begin()->second, value_type(-1) - last, results);
134 void vnodes(std::vector<std::pair<value_type, value_type> > & results)
const{
135 results.resize(ring_.size());
136 std::copy(ring_.begin(), ring_.end(), results.begin());
138 static void addWeight(value_type value, value_type weight, std::vector<std::pair<value_type, value_type> > & results){
139 typedef std::vector<std::pair<value_type, value_type> > __Ret;
140 for(__Ret::iterator it = results.begin();it != results.end();++it)
141 if(it->first == value){
142 it->second += weight;
145 results.push_back(std::make_pair(value, weight));
149 void insertNode(value_type value,
size_t weight, __Node & n){
150 while(n.weight() < weight){
151 n.last_ = hashValue(value, n.weight(), n.last_);
152 std::pair<typename __Map::iterator, bool> ret = ring_.insert(std::make_pair(n.last_, value));
154 n.pos_.push_back(n.last_);
157 void removeNode(value_type value,
size_t weight, __Node & n){
158 while(n.weight() > weight){
159 ring_.erase(n.pos_.back());
161 n.last_ = (n.pos_.empty() ? 0 : n.pos_.back());
164 static value_type hashValue(value_type key,
size_t index, value_type last){
165 return u32Hash(key + last + (index << 16) + (index >> 16));
167 static value_type u32Hash(value_type val){
168 val = ((val >> 16) ^ val) * 0x45d9f3b + 1;
169 val = ((val >> 16) ^ val) * 0x45d9f3b + 3;
170 val = ((val >> 16) ^ val);
A lightweight implementation of Consistent Hashng algorithm.
Definition: consistent_hash.hh:71
value_type hash(const key_type &key) const
Get consistent hash result of a key.
Definition: consistent_hash.hh:94
void setValue(value_type value, size_t weight=1000)
Add, remove or modify weight of a value.
Definition: consistent_hash.hh:107
Definition: template.hh:174