Skip to content

Commit

Permalink
mutex lock to prevent rc
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrostami committed May 2, 2020
1 parent 3f44594 commit b818109
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,9 @@ fmt.println(node) // this will print out one of the nodes
Benchmark
`go test -bench=.`

Race Condition
`go test --race`
Thanks to **Mohammad Rajabloo** for reporting the race issue

Tests
`go test`
8 changes: 8 additions & 0 deletions consistenthash.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"hash/crc32"
"sort"
"strconv"
"sync"
)

// HashFunc hash function to generate random hash
type HashFunc func(data []byte) uint32

// ConsistentHash everything we need for CH
type ConsistentHash struct {
sync.RWMutex
hash HashFunc
defaultReplicas int // default number of replicas in hash ring (higher number means more posibility for balance equality)
hKeys []uint32 // Sorted
Expand Down Expand Up @@ -59,6 +61,8 @@ func (ch *ConsistentHash) Get(key string) string {
if ch.IsEmpty() {
return ""
}
ch.RLock()
defer ch.RUnlock()
hash := ch.hash([]byte(key))

// Binary search for appropriate replica
Expand All @@ -77,6 +81,8 @@ func (ch *ConsistentHash) Remove(key string) bool {
return true
}
replicas := ch.rTable[key]
ch.Lock()
defer ch.Unlock()
for i := 0; i < replicas; i++ {
hash := ch.hash([]byte(strconv.Itoa(i) + key))
delete(ch.hTable, hash) // delete replica
Expand All @@ -98,6 +104,8 @@ func (ch *ConsistentHash) removeHashKey(hash uint32) {

// add inserts new hash in hash table
func (ch *ConsistentHash) add(key string, replicas int) {
ch.Lock()
defer ch.Unlock()
for i := 0; i < replicas; i++ {
hash := ch.hash([]byte(strconv.Itoa(i) + key))
ch.hKeys = append(ch.hKeys, hash)
Expand Down
10 changes: 10 additions & 0 deletions consistenthash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ func TestReplication(t *testing.T) {
}
}

func TestConcurrency(t *testing.T) {
hash := NewConsistentHash(1, nil)
items := []string{"Bill", "Bob", "Bonny", "Bob", "Bill", "Bony", "Bob"}
for _, item := range items {
go func(it string) {
hash.Add(it)
}(item)
}
}

func TestConsistency(t *testing.T) {
hash1 := NewConsistentHash(1, nil)
hash2 := NewConsistentHash(1, nil)
Expand Down

0 comments on commit b818109

Please sign in to comment.