验证中...
Languages: Go
Categories: 编程语言基础
Latest update 2019-08-14 10:10
BatchMap.go
Raw Copy
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"sync"
"time"
)
type BatchMap struct {
maps map[string]*sync.Map
counters map[string]int64
mutex sync.RWMutex
}
func NewBatchMap() *BatchMap {
return &BatchMap{
maps: make(map[string]*sync.Map),
counters: make(map[string]int64),
}
}
func (bm *BatchMap) hash(key interface{}) string {
v := md5.Sum([]byte(fmt.Sprintf("%v", key)))
return hex.EncodeToString([]byte(v[4:]))[:1]
}
func (bm *BatchMap) counter(key string, count int64) int64 {
bm.mutex.Lock()
defer bm.mutex.Unlock()
if _, ok := bm.counters[key]; !ok {
bm.counters[key] = 0
}
bm.counters[key] += count
return bm.counters[key]
}
func (bm *BatchMap) Len() (c int64) {
bm.mutex.RLock()
defer bm.mutex.RUnlock()
for _, v := range bm.counters {
c += v
}
return
}
func (bm *BatchMap) Store(key, value interface{}) {
k := bm.hash(key)
if _, ok := bm.maps[k]; !ok {
bm.maps[k] = new(sync.Map)
}
if _, ok := bm.maps[k].Load(key); !ok {
bm.counter(k, 1)
}
bm.maps[k].Store(key, value)
}
func (bm *BatchMap) Load(key interface{}) (interface{}, bool) {
k := bm.hash(key)
if v, ok := bm.maps[k]; ok {
return v.Load(key)
}
return nil, false
}
func (bm *BatchMap) Delete(key interface{}) {
k := bm.hash(key)
if v, ok := bm.maps[k]; ok {
if _, ok := v.Load(key); ok {
bm.maps[k].Delete(key)
bm.counter(k, -1)
}
}
}
func (bm *BatchMap) Range(fn func(key, value interface{}) bool) {
var wg sync.WaitGroup
for _, m := range bm.maps {
wg.Add(1)
go func(m *sync.Map) {
m.Range(fn)
wg.Done()
}(m)
}
wg.Wait()
}
func main() {
batchMap := NewBatchMap()
for i := 0; i < 1000; i++ {
batchMap.Store(i, time.Now().Unix())
}
fmt.Println(batchMap.counters)
batchMap.Range(func(key, value interface{}) bool {
fmt.Println(key, value)
return true
})
}

Comment list( 0 )

You need to Sign in for post a comment

Help Search