Golang的一致性哈希实现
一致性哈希的具体介绍,可以参考:http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html
1 import ( 2 "hash/crc32" 3 "sort" 4 "strconv" 5 "sync" 6 ) 7 8 const DEFAULT_REPLICAS = 100 9 type SortKeys []uint32 10 11 func (sk SortKeys) Len() int { 12 return len(sk) 13 } 14 15 func (sk SortKeys) Less(i, j int) bool { 16 return sk[i] < sk[j] 17 } 18 19 func (sk SortKeys) Swap(i, j int) { 20 sk[i], sk[j] = sk[j], sk[i] 21 } 22 23 type HashRing struct { 24 Nodes map[uint32]string 25 Keys SortKeys 26 sync.RWMutex 27 } 28 29 func (hr *HashRing)New(nodes []string) { 30 if nodes == nil { 31 return 32 } 33 34 hr.Nodes = make(map[uint32]string) 35 hr.Keys = SortKeys{} 36 for _, node := range(nodes) { 37 for i := 0; i < DEFAULT_REPLICAS; i++ { 38 str := node + strconv.Itoa(i) 39 hr.Nodes[hr.hashStr(str)] = node 40 hr.Keys = append(hr.Keys, hr.hashStr(str)) 41 } 42 } 43 sort.Sort(hr.Keys) 44 } 45 46 func (hr *HashRing) hashStr(key string) uint32 { 47 return crc32.ChecksumIEEE([]byte(key)) 48 } 49 50 func (hr *HashRing) GetNode(key string) string { 51 hr.RLock() 52 defer hr.RUnlock() 53 hash := hr.hashStr(key) 54 i := hr.get_position(hash) 55 return hr.Nodes[hr.Keys[i]] 56 } 57 58 func (hr *HashRing) get_position(hash uint32) int { 59 i := sort.Search(len(hr.Keys), func(i int) bool { 60 return hr.Keys[i] >= hash}) 61 62 if i < len(hr.Keys) { 63 if i == len(hr.Keys) - 1 { 64 return 0 65 } else { 66 return i 67 } 68 } else { 69 return len(hr.Keys) - 1 70 } 71 } 72 73