github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/collection/skipmap/skipmap_str_test.go (about) 1 // Copyright 2021 ByteDance Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package skipmap 16 17 import ( 18 "reflect" 19 "strconv" 20 "sync" 21 "sync/atomic" 22 "testing" 23 ) 24 25 func TestStringMap(t *testing.T) { 26 m := NewString() 27 28 // Correctness. 29 m.Store("123", "123") 30 v, ok := m.Load("123") 31 if !ok || v != "123" || m.Len() != 1 { 32 t.Fatal("invalid") 33 } 34 35 m.Store("123", "456") 36 v, ok = m.Load("123") 37 if !ok || v != "456" || m.Len() != 1 { 38 t.Fatal("invalid") 39 } 40 41 m.Store("123", 456) 42 v, ok = m.Load("123") 43 if !ok || v != 456 || m.Len() != 1 { 44 t.Fatal("invalid") 45 } 46 47 m.Delete("123") 48 _, ok = m.Load("123") 49 if ok || m.Len() != 0 { 50 t.Fatal("invalid") 51 } 52 53 _, ok = m.LoadOrStore("123", 456) 54 if ok || m.Len() != 1 { 55 t.Fatal("invalid") 56 } 57 58 v, ok = m.Load("123") 59 if !ok || v != 456 || m.Len() != 1 { 60 t.Fatal("invalid") 61 } 62 63 v, ok = m.LoadAndDelete("123") 64 if !ok || v != 456 || m.Len() != 0 { 65 t.Fatal("invalid") 66 } 67 68 _, ok = m.LoadOrStore("123", 456) 69 if ok || m.Len() != 1 { 70 t.Fatal("invalid") 71 } 72 73 m.LoadOrStore("456", 123) 74 if ok || m.Len() != 2 { 75 t.Fatal("invalid") 76 } 77 78 m.Range(func(key string, value interface{}) bool { 79 if key == "123" { 80 m.Store("123", 123) 81 } else if key == "456" { 82 m.LoadAndDelete("456") 83 } 84 return true 85 }) 86 87 v, ok = m.Load("123") 88 if !ok || v != 123 || m.Len() != 1 { 89 t.Fatal("invalid") 90 } 91 92 // Concurrent. 93 var wg sync.WaitGroup 94 for i := 0; i < 1000; i++ { 95 i := i 96 wg.Add(1) 97 go func() { 98 n := strconv.Itoa(i) 99 m.Store(n, int(i+1000)) 100 wg.Done() 101 }() 102 } 103 wg.Wait() 104 var count2 int64 105 m.Range(func(key string, value interface{}) bool { 106 atomic.AddInt64(&count2, 1) 107 return true 108 }) 109 m.Delete("600") 110 var count int64 111 m.Range(func(key string, value interface{}) bool { 112 atomic.AddInt64(&count, 1) 113 return true 114 }) 115 116 val, ok := m.Load("500") 117 if !ok || reflect.TypeOf(val).Kind().String() != "int" || val.(int) != 1500 { 118 t.Fatal("fail") 119 } 120 121 _, ok = m.Load("600") 122 if ok { 123 t.Fatal("fail") 124 } 125 126 if m.Len() != 999 || int(count) != m.Len() { 127 t.Fatal("fail", m.Len(), count, count2) 128 } 129 }