test: 完善 hub.ObjectPool 测试用例
This commit is contained in:
parent
161fbfe4e3
commit
c439ef6424
|
@ -1,16 +1,14 @@
|
|||
package hub
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// NewObjectPool 创建一个线程安全的对象缓冲池
|
||||
// - 通过 Get 获取一个对象,如果缓冲区内存在可用对象则直接返回,否则新建一个进行返回
|
||||
// - 通过 Release 将使用完成的对象放回缓冲区,超出缓冲区大小的对象将被放弃
|
||||
// NewObjectPool 创建一个 ObjectPool
|
||||
func NewObjectPool[T any](generator func() *T, releaser func(data *T)) *ObjectPool[*T] {
|
||||
if generator == nil || releaser == nil {
|
||||
panic(errors.New("generator or releaser is nil"))
|
||||
panic(fmt.Errorf("generator and releaser can not be nil, generator check: %v, releaser check: %v", generator != nil, releaser != nil))
|
||||
}
|
||||
return &ObjectPool[*T]{
|
||||
releaser: releaser,
|
||||
|
@ -22,10 +20,8 @@ func NewObjectPool[T any](generator func() *T, releaser func(data *T)) *ObjectPo
|
|||
}
|
||||
}
|
||||
|
||||
// ObjectPool 线程安全的对象缓冲池
|
||||
// ObjectPool 基于 sync.Pool 实现的线程安全的对象池
|
||||
// - 一些高频临时生成使用的对象可以通过 ObjectPool 进行管理,例如属性计算等
|
||||
// - 缓冲区内存在可用对象时直接返回,否则新建一个进行返回
|
||||
// - 通过 Release 将使用完成的对象放回缓冲区,超出缓冲区大小的对象将被放弃
|
||||
type ObjectPool[T any] struct {
|
||||
p sync.Pool
|
||||
releaser func(data T)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package hub_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
"github.com/kercylan98/minotaur/utils/hub"
|
||||
)
|
||||
|
||||
func ExampleNewObjectPool() {
|
||||
var p = hub.NewObjectPool[map[int]int](func() *map[int]int {
|
||||
return &map[int]int{}
|
||||
}, func(data *map[int]int) {
|
||||
collection.ClearMap(*data)
|
||||
})
|
||||
|
||||
m := *p.Get()
|
||||
m[1] = 1
|
||||
p.Release(&m)
|
||||
fmt.Println(m)
|
||||
// Output:
|
||||
// map[]
|
||||
}
|
|
@ -1 +1,93 @@
|
|||
package hub_test
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/hub"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewObjectPool(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
generator func() *map[string]int
|
||||
releaser func(data *map[string]int)
|
||||
shouldPanic bool
|
||||
}{
|
||||
{name: "TestNewObjectPool_NilGenerator", generator: nil, releaser: func(data *map[string]int) {}, shouldPanic: true},
|
||||
{name: "TestNewObjectPool_NilReleaser", generator: func() *map[string]int { return &map[string]int{} }, releaser: nil, shouldPanic: true},
|
||||
{name: "TestNewObjectPool_NilGeneratorAndReleaser", generator: nil, releaser: nil, shouldPanic: true},
|
||||
{name: "TestNewObjectPool_Normal", generator: func() *map[string]int { return &map[string]int{} }, releaser: func(data *map[string]int) {}, shouldPanic: false},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
defer func() {
|
||||
if err := recover(); c.shouldPanic && err == nil {
|
||||
t.Error("TestNewObjectPool should panic")
|
||||
}
|
||||
}()
|
||||
_ = hub.NewObjectPool[map[string]int](c.generator, c.releaser)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestObjectPool_Get(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
generator func() *map[string]int
|
||||
releaser func(data *map[string]int)
|
||||
}{
|
||||
{
|
||||
name: "TestObjectPool_Get_Normal",
|
||||
generator: func() *map[string]int {
|
||||
return &map[string]int{}
|
||||
},
|
||||
releaser: func(data *map[string]int) {
|
||||
for k := range *data {
|
||||
delete(*data, k)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
pool := hub.NewObjectPool[map[string]int](c.generator, c.releaser)
|
||||
if actual := pool.Get(); len(*actual) != 0 {
|
||||
t.Error("TestObjectPool_Get failed")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestObjectPool_Release(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
generator func() *map[string]int
|
||||
releaser func(data *map[string]int)
|
||||
}{
|
||||
{
|
||||
name: "TestObjectPool_Release_Normal",
|
||||
generator: func() *map[string]int {
|
||||
return &map[string]int{}
|
||||
},
|
||||
releaser: func(data *map[string]int) {
|
||||
for k := range *data {
|
||||
delete(*data, k)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
pool := hub.NewObjectPool[map[string]int](c.generator, c.releaser)
|
||||
msg := pool.Get()
|
||||
m := *msg
|
||||
m["test"] = 1
|
||||
pool.Release(msg)
|
||||
if len(m) != 0 {
|
||||
t.Error("TestObjectPool_Release failed")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue