-
Notifications
You must be signed in to change notification settings - Fork 1
/
sharded_map.go
68 lines (62 loc) · 1.55 KB
/
sharded_map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package scache
import (
"github.com/dolthub/swiss"
"sync"
)
// shardedMap represents sharded map
type shardedMap struct {
config Config
lock []sync.RWMutex
maps []*swiss.Map[uint64, uint32]
hasher fnv64a
shardsHash uint64
}
func (m *shardedMap) getAddress(key string) uint64 {
hashedKey := m.hasher.Sum64(key)
index := hashedKey & m.shardsHash
m.lock[index].RLock()
if m.maps[index].Count() == 0 {
m.lock[index].RUnlock()
return 0
}
value, _ := m.maps[index].Get(hashedKey)
m.lock[index].RUnlock()
return uint64(value) << 5
}
func (m *shardedMap) put(key string, value uint32) bool {
hashedKey := m.hasher.Sum64(key)
index := hashedKey & m.shardsHash
m.lock[index].Lock()
_, has := m.maps[index].Get(hashedKey)
m.maps[index].Put(hashedKey, value)
m.lock[index].Unlock()
return has
}
func (m *shardedMap) delete(key string) bool {
hashedKey := m.hasher.Sum64(key)
index := hashedKey & m.shardsHash
m.lock[index].Lock()
if m.maps[index].Count() == 0 {
m.lock[index].Unlock()
return false
}
value, _ := m.maps[index].Get(hashedKey)
m.maps[index].Put(hashedKey, 0)
m.lock[index].Unlock()
return value > 0
}
func newShardedMap(config *Config) *shardedMap {
if config.Shards == 0 {
config.Shards = 100
}
aMap := &shardedMap{
config: *config,
lock: make([]sync.RWMutex, config.Shards),
maps: make([]*swiss.Map[uint64, uint32], config.Shards),
shardsHash: config.Shards - 1,
}
for i := range aMap.maps {
aMap.maps[i] = swiss.NewMap[uint64, uint32](uint32(config.shardMapSize))
}
return aMap
}