You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
2.9 KiB
149 lines
2.9 KiB
package collect |
|
|
|
import ( |
|
"fmt" |
|
"math/rand" |
|
"strconv" |
|
"sync" |
|
"testing" |
|
"time" |
|
) |
|
|
|
func TestRemove(t *testing.T) { |
|
m := map[string][]int{ |
|
"name": {1, 2, 3, 4, 5, 6}, |
|
} |
|
arr := m["name"] |
|
Remove(&arr, func(v int) bool { |
|
return true |
|
}) |
|
fmt.Println(arr) |
|
fmt.Println(m["name"]) |
|
} |
|
|
|
func TestConcurrentMap(t *testing.T) { |
|
cm := NewConcurrentMap[string, string](19, func(k string) string { return k }) |
|
concurrent := 1000 |
|
|
|
wg := sync.WaitGroup{} |
|
wg.Add(concurrent) |
|
|
|
for i := 0; i < concurrent; i++ { |
|
go func(loop int) { |
|
for j := 0; j < concurrent; j++ { |
|
k := fmt.Sprintf("%d-%d", loop, j) |
|
cm.Store(k, k) |
|
} |
|
wg.Done() |
|
}(i) |
|
} |
|
wg.Wait() |
|
|
|
var sum int |
|
cm.RangeUpdate(func(key, value string) (bool, bool, string) { |
|
if key != value { |
|
panic(fmt.Errorf("value load error: %s:%s", key, value)) |
|
} |
|
return true, false, value + "-update" |
|
}) |
|
cm.Range(func(key, value string) bool { |
|
sum++ |
|
if (key + "-update") != value { |
|
panic(fmt.Errorf("value update error: %s:%s", key, value)) |
|
} |
|
return true |
|
}) |
|
if sum != (concurrent * concurrent) { |
|
t.Errorf("count error: %d", sum) |
|
} |
|
|
|
wg.Add(concurrent) |
|
for i := 0; i < concurrent; i++ { |
|
go func() { |
|
r := rand.New(rand.NewSource(time.Now().UnixMilli())) |
|
for i := 0; i < concurrent; i++ { |
|
k := fmt.Sprintf("%d-%d", r.Intn(concurrent), r.Intn(concurrent)) |
|
v, ok := cm.Load(k) |
|
if !ok || (k+"-update") != v { |
|
panic(fmt.Errorf("value load error: %s", k)) |
|
} |
|
} |
|
wg.Done() |
|
}() |
|
} |
|
wg.Wait() |
|
} |
|
|
|
type counter struct { |
|
c int |
|
} |
|
|
|
func (c *counter) increment() { |
|
c.c += 1 |
|
} |
|
|
|
func TestComputeIfAbsent(t *testing.T) { |
|
cm := NewConcurrentMap[int, *counter](16, func(k int) string { return strconv.Itoa(k) }) |
|
concurrent := 1000 |
|
add := 10 |
|
wg := &sync.WaitGroup{} |
|
wg.Add(concurrent) |
|
|
|
for i := 0; i < concurrent; i++ { |
|
go func() { |
|
defer wg.Done() |
|
|
|
r := rand.New(rand.NewSource(time.Now().UnixMilli())) |
|
v := cm.ComputeIfAbsent(r.Intn(10), func(k int) *counter { |
|
return &counter{} |
|
}) |
|
for i := 0; i < add; i++ { |
|
v.increment() |
|
} |
|
}() |
|
} |
|
|
|
wg.Wait() |
|
|
|
cm.Range(func(k int, v *counter) bool { |
|
if v.c != add { |
|
t.Error("error value...") |
|
} |
|
return true |
|
}) |
|
} |
|
|
|
func TestBenchmark(t *testing.T) { |
|
cm := NewConcurrentMap[string, int](16, func(s string) string { return s }) |
|
for i := range 10000 { |
|
cm.Store(strconv.Itoa(i), i) |
|
} |
|
|
|
// sm := &sync.Map{} |
|
// for i := range 10000 { |
|
// sm.Store(strconv.Itoa(i), i) |
|
// } |
|
|
|
// mm := make(map[string]int, 10000) |
|
// for i := range 10000 { |
|
// mm[strconv.Itoa(i)] = i |
|
// } |
|
wg := &sync.WaitGroup{} |
|
for range 4 { |
|
wg.Add(1) |
|
go func() { |
|
defer wg.Done() |
|
|
|
now := time.Now() |
|
for range 10000 { |
|
for i := range 10000 { |
|
_, _ = cm.Load(strconv.Itoa(i)) |
|
// _, _ = sm.Load(strconv.Itoa(i)) |
|
// _, _ = mm[strconv.Itoa(i)] |
|
} |
|
} |
|
fmt.Printf("done: use %dms\n", time.Now().UnixMilli()-now.UnixMilli()) |
|
}() |
|
} |
|
wg.Wait() |
|
}
|
|
|