一致性哈希的实现理解 1 namespace 2 { 3 4 class StringifyException 5 { 6 }; 7 8 template <class T> 9 std::string Stringify(const T& t) 10 { 11 std::ostringstream os; 12 if (!(os << t)) 13 { 14 throw StringifyException(); 15 } 16 return os.str(); 17 } 18 19 template <> 20 std::string Stringify(const std::string& str) 21 { 22 return str; 23 } 24 25 template <> 26 std::string Stringify(const char* const& str) 27 { 28 return str; 29 } 30 } 31 32 namespace Consistent 33 { 34 35 class EmptyRingException 36 { 37 }; 38 39 template <class Node, class Data, class Hash = HASH_NAMESPACE::hash<const char*> > 40 class HashRing 41 { 42 public: 43 typedef std::map<size_t, Node> NodeMap; 44 45 HashRing(unsigned int replicas) 46 : replicas_(replicas), hash_(HASH_NAMESPACE::hash<const char*>()) 47 { 48 } 49 50 HashRing(unsigned int replicas, const Hash& hash) 51 : replicas_(replicas), hash_(hash) 52 { 53 } 54 55 size_t AddNode(const Node& node); 56 void RemoveNode(const Node& node); 57 const Node& GetNode(const Data& data) const; 58 59 private: 60 NodeMap ring_; 61 const unsigned int replicas_; 62 Hash hash_; 63 }; 64 65 template <class Node, class Data, class Hash> 66 size_t HashRing<Node, Data, Hash>::AddNode(const Node& node) 67 { 68 size_t hash; 69 std::string nodestr = Stringify(node); 70 for (unsigned int r = 0; r < replicas_; r++) 71 { 72 hash = hash_((nodestr + Stringify(r)).c_str()); 73 ring_[hash] = node; 74 } 75 return hash; 76 } 77 78 template <class Node, class Data, class Hash> 79 void HashRing<Node, Data, Hash>::RemoveNode(const Node& node) 80 { 81 std::string nodestr = Stringify(node); 82 for (unsigned int r = 0; r < replicas_; r++) 83 { 84 size_t hash = hash_((nodestr + Stringify(r)).c_str()); 85 ring_.erase(hash); 86 } 87 } 88 89 template <class Node, class Data, class Hash> 90 const Node& HashRing<Node, Data, Hash>::GetNode(const Data& data) const 91 { 92 if (ring_.empty()) 93 throw EmptyRingException(); 94 95 size_t hash = hash_(Stringify(data).c_str()); 96 typename NodeMap::const_iterator it; 97 // Look for the first node >= hash 98 it = ring_.lower_bound(hash); 99 if (it == ring_.end()) 100 { 101 // Wrapped around; get the first node 102 it = ring_.begin(); 103 } 104 return it->second; 105 } 106 }
时间: 2024-10-15 23:54:29