github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/maps/skipmap/skipmap_str_test.go (about) 1 package skipmap 2 3 import ( 4 "reflect" 5 "strconv" 6 "sync" 7 "sync/atomic" 8 "testing" 9 10 "github.com/songzhibin97/go-baseutils/base/bcomparator" 11 ) 12 13 func TestStringMap(t *testing.T) { 14 m := New[string, any](bcomparator.StringComparator()) 15 16 // Correctness. 17 m.Store("123", "123") 18 v, ok := m.Load("123") 19 if !ok || v != "123" || m.Len() != 1 { 20 t.Fatal("invalid") 21 } 22 23 m.Store("123", "456") 24 v, ok = m.Load("123") 25 if !ok || v != "456" || m.Len() != 1 { 26 t.Fatal("invalid") 27 } 28 29 m.Store("123", 456) 30 v, ok = m.Load("123") 31 if !ok || v != 456 || m.Len() != 1 { 32 t.Fatal("invalid") 33 } 34 35 m.Delete("123") 36 _, ok = m.Load("123") 37 if ok || m.Len() != 0 { 38 t.Fatal("invalid") 39 } 40 41 _, ok = m.LoadOrStore("123", 456) 42 if ok || m.Len() != 1 { 43 t.Fatal("invalid") 44 } 45 46 v, ok = m.Load("123") 47 if !ok || v != 456 || m.Len() != 1 { 48 t.Fatal("invalid") 49 } 50 51 v, ok = m.LoadAndDelete("123") 52 if !ok || v != 456 || m.Len() != 0 { 53 t.Fatal("invalid") 54 } 55 56 _, ok = m.LoadOrStore("123", 456) 57 if ok || m.Len() != 1 { 58 t.Fatal("invalid") 59 } 60 61 m.LoadOrStore("456", 123) 62 if ok || m.Len() != 2 { 63 t.Fatal("invalid") 64 } 65 66 m.Range(func(key string, value interface{}) bool { 67 if key == "123" { 68 m.Store("123", 123) 69 } else if key == "456" { 70 m.LoadAndDelete("456") 71 } 72 return true 73 }) 74 75 v, ok = m.Load("123") 76 if !ok || v != 123 || m.Len() != 1 { 77 t.Fatal("invalid") 78 } 79 80 // Concurrent. 81 var wg sync.WaitGroup 82 for i := 0; i < 1000; i++ { 83 i := i 84 wg.Add(1) 85 go func() { 86 n := strconv.Itoa(i) 87 m.Store(n, int(i+1000)) 88 wg.Done() 89 }() 90 } 91 wg.Wait() 92 var count2 int64 93 m.Range(func(key string, value interface{}) bool { 94 atomic.AddInt64(&count2, 1) 95 return true 96 }) 97 m.Delete("600") 98 var count int64 99 m.Range(func(key string, value interface{}) bool { 100 atomic.AddInt64(&count, 1) 101 return true 102 }) 103 104 val, ok := m.Load("500") 105 if !ok || reflect.TypeOf(val).Kind().String() != "int" || val.(int) != 1500 { 106 t.Fatal("fail") 107 } 108 109 _, ok = m.Load("600") 110 if ok { 111 t.Fatal("fail") 112 } 113 114 if m.Len() != 999 || int(count) != m.Len() { 115 t.Fatal("fail", m.Len(), count, count2) 116 } 117 }