From: qydysky Date: Thu, 18 Feb 2021 05:40:10 +0000 (+0800) Subject: map range X-Git-Tag: v0.4.3 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=cab6325b87bb82d733778837c28463d3ceb2c813;p=part%2F.git map range --- diff --git a/map/Map.go b/map/Map.go index 97dafdb..37d8f84 100644 --- a/map/Map.go +++ b/map/Map.go @@ -71,6 +71,26 @@ func (t *Map) LoadV(k interface{}) (v interface{}) { return } +func (t *Map) Range(f func(key, value interface{})(bool)) { + t.lock.Lock() + + m,_ := t.readOnly.Load().(map[interface{}]*ptr) + if t.m == nil {t.mapFrom(&m)} + t.readOnly.Store(t.m) + t.m = nil + t.num = 0 + + t.lock.Unlock() + + for k,p := range m{ + v,ok := p.tryLoad() + if !ok {continue} + if !f(k,v) {return} + } + + return +} + func (t *Map) Delete(k interface{}) { m,_ := t.readOnly.Load().(map[interface{}]*ptr) diff --git a/map/Map_test.go b/map/Map_test.go index 9e6d9a5..ecdcb0a 100644 --- a/map/Map_test.go +++ b/map/Map_test.go @@ -11,11 +11,17 @@ func Test_customMap(t *testing.T) { c.Store(0, 3) if v,ok := c.Load(0);ok && v != 3{t.Error(`1`)} //change - c.Store(0, 1) - if v,ok := c.Load(0);ok && v != 1{t.Error(`2`)} + c.Store(0, 0) + if v,ok := c.Load(0);ok && v != 0{t.Error(`2`)} + //range + c.Store(1, 1) + c.Range(func(key,value interface{})(bool){ + if key.(int) != value.(int) {t.Error(`3`)} + return true + }) //del c.Store(0, nil) - if v,ok := c.Load(0);ok && v != nil{t.Error(`3`)} + if v,ok := c.Load(0);ok && v != nil{t.Error(`4`)} } func Benchmark_customMap_Set(b *testing.B) { @@ -102,8 +108,6 @@ func Benchmark_customMap_SetGet(b *testing.B) { } w.Wait() - b.Log(c.Len()) - w.Add(b.N) w.Add(b.N) b.ResetTimer() @@ -122,6 +126,28 @@ func Benchmark_customMap_SetGet(b *testing.B) { w.Wait() } +func Benchmark_customMap_Range(b *testing.B) { + var c Map + var w = &sync.WaitGroup{} + var t = 900000//b.N + + w.Add(t) + b.ResetTimer() + for i := 0; i < t; i++ { + go func(index int) { + c.Store(index, index) + w.Done() + }(i) + } + w.Wait() + + b.ResetTimer() + c.Range(func(k,v interface{})(bool){ + if k.(int) != v.(int) {b.Error(`p`)} + return true + }) +} + func Benchmark_syncMap_Set(b *testing.B) { c:=new(sync.Map) var w = &sync.WaitGroup{} @@ -216,3 +242,25 @@ func Benchmark_syncMap_SetGet(b *testing.B) { } w.Wait() } + +func Benchmark_syncMap_Range(b *testing.B) { + var c sync.Map + var w = &sync.WaitGroup{} + var t = 900000//b.N + + w.Add(t) + b.ResetTimer() + for i := 0; i < t; i++ { + go func(index int) { + c.Store(index, index) + w.Done() + }(i) + } + w.Wait() + + b.ResetTimer() + c.Range(func(k,v interface{})(bool){ + if k.(int) != v.(int) {b.Error(`p`)} + return true + }) +} \ No newline at end of file