...
1
16
17
18 package consistenthash
19
20 import (
21 "hash/crc32"
22 "sort"
23 "strconv"
24 )
25
26 type Hash func(data []byte) uint32
27
28 type Map struct {
29 hash Hash
30 replicas int
31 keys []int
32 hashMap map[int]string
33 }
34
35 func New(replicas int, fn Hash) *Map {
36 m := &Map{
37 replicas: replicas,
38 hash: fn,
39 hashMap: make(map[int]string),
40 }
41 if m.hash == nil {
42 m.hash = crc32.ChecksumIEEE
43 }
44 return m
45 }
46
47
48 func (m *Map) IsEmpty() bool {
49 return len(m.keys) == 0
50 }
51
52
53 func (m *Map) Add(keys ...string) {
54 for _, key := range keys {
55 for i := 0; i < m.replicas; i++ {
56 hash := int(m.hash([]byte(strconv.Itoa(i) + key)))
57 m.keys = append(m.keys, hash)
58 m.hashMap[hash] = key
59 }
60 }
61 sort.Ints(m.keys)
62 }
63
64
65 func (m *Map) Get(key string) string {
66 if m.IsEmpty() {
67 return ""
68 }
69
70 hash := int(m.hash([]byte(key)))
71
72
73 idx := sort.Search(len(m.keys), func(i int) bool { return m.keys[i] >= hash })
74
75
76 if idx == len(m.keys) {
77 idx = 0
78 }
79
80 return m.hashMap[m.keys[idx]]
81 }
82
View as plain text