From: qydysky Date: Sun, 11 May 2025 19:03:28 +0000 (+0800) Subject: 1 (#53) X-Git-Tag: v0.28.20250511190336 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=e08e04fb6e272a3363c1a92e0b839c308ef8a9d7;p=part%2F.git 1 (#53) * 1 * 1 * 1 * 1 --- diff --git a/.github/workflows/test1.yml b/.github/workflows/test1.yml index a32c866..ccd425e 100644 --- a/.github/workflows/test1.yml +++ b/.github/workflows/test1.yml @@ -39,6 +39,7 @@ jobs: go test -count 1 -timeout 5s -v -race github.com/qydysky/part/component2 go test -count 1 -timeout 20s -v -race github.com/qydysky/part/ctx go test -count 1 -timeout 10s -v -race github.com/qydysky/part/slice + go test -count 1 -timeout 10s -v github.com/qydysky/part/slice go test -count 1 -timeout 5s -v -race github.com/qydysky/part/bools go test -count 1 -timeout 5s -v -race github.com/qydysky/part/errors go test -count 1 -timeout 5s -v -race github.com/qydysky/part/crypto/... @@ -78,6 +79,7 @@ jobs: go test -count 1 -timeout 5s -v -race github.com/qydysky/part/component2 go test -count 1 -timeout 20s -v -race github.com/qydysky/part/ctx go test -count 1 -timeout 10s -v -race github.com/qydysky/part/slice + go test -count 1 -timeout 10s -v github.com/qydysky/part/slice go test -count 1 -timeout 5s -v -race github.com/qydysky/part/bools go test -count 1 -timeout 5s -v -race github.com/qydysky/part/errors go test -count 1 -timeout 5s -v -race github.com/qydysky/part/crypto/... @@ -117,6 +119,7 @@ jobs: go test -count 1 -timeout 5s -v -race github.com/qydysky/part/component2 go test -count 1 -timeout 20s -v -race github.com/qydysky/part/ctx go test -count 1 -timeout 10s -v -race github.com/qydysky/part/slice + go test -count 1 -timeout 10s -v github.com/qydysky/part/slice go test -count 1 -timeout 5s -v -race github.com/qydysky/part/bools go test -count 1 -timeout 5s -v -race github.com/qydysky/part/errors go test -count 1 -timeout 5s -v -race github.com/qydysky/part/crypto/... diff --git a/idpool/Idpool.go b/idpool/Idpool.go index df46ca7..7367ca5 100644 --- a/idpool/Idpool.go +++ b/idpool/Idpool.go @@ -6,23 +6,23 @@ import ( "unsafe" ) -type Idpool struct { +type Idpool[T any] struct { pool sync.Pool sum int64 - initF func() interface{} + initF func() *T } -type Id struct { +type Id[T any] struct { Id uintptr - Item interface{} + Item *T } -func New(f func() interface{}) *Idpool { - return &Idpool{ +func New[T any](f func() *T) *Idpool[T] { + return &Idpool[T]{ initF: f, pool: sync.Pool{ - New: func() interface{} { - var o = new(Id) + New: func() any { + var o = new(Id[T]) o.Item = f() o.Id = uintptr(unsafe.Pointer(&o.Item)) return o @@ -31,8 +31,8 @@ func New(f func() interface{}) *Idpool { } } -func (t *Idpool) Get() (o *Id) { - o = t.pool.Get().(*Id) +func (t *Idpool[T]) Get() (o *Id[T]) { + o = t.pool.Get().(*Id[T]) if o.Item == nil { o.Item = t.initF() o.Id = uintptr(unsafe.Pointer(&o.Item)) @@ -41,14 +41,16 @@ func (t *Idpool) Get() (o *Id) { return } -func (t *Idpool) Put(i *Id) { - if i.Item == nil { - return +func (t *Idpool[T]) Put(is ...*Id[T]) { + for _, i := range is { + if i.Item == nil { + continue + } + t.pool.Put(i) + atomic.AddInt64(&t.sum, -1) } - t.pool.Put(i) - atomic.AddInt64(&t.sum, -1) } -func (t *Idpool) Len() int64 { +func (t *Idpool[T]) InUse() int64 { return atomic.LoadInt64(&t.sum) } diff --git a/idpool/Idpool_test.go b/idpool/Idpool_test.go index 11dabbb..ed360f3 100644 --- a/idpool/Idpool_test.go +++ b/idpool/Idpool_test.go @@ -7,18 +7,21 @@ import ( type test struct{} func Test(t *testing.T) { - pool := New(func() interface{} { + pool := New(func() *test { return &test{} }) a := pool.Get() b := pool.Get() - t.Log(a.Id, a.Item, pool.Len()) - t.Log(b.Id, b.Item) - pool.Put(a) - pool.Put(a) - t.Log(a.Id, a.Item, pool.Len()) - t.Log(b.Id, b.Item) + if pool.InUse() != 2 { + t.Fatal() + } + bid := b.Id + pool.Put(b) + if pool.InUse() != 1 { + t.Fatal() + } a = pool.Get() - t.Log(a.Id, a.Item, pool.Len()) - t.Log(b.Id, b.Item) + if bid != a.Id { + t.Fatal() + } } diff --git a/slice/Blocks.go b/slice/Blocks.go index b85c4bb..8faf792 100644 --- a/slice/Blocks.go +++ b/slice/Blocks.go @@ -3,6 +3,7 @@ package part import ( "errors" "runtime" + "sync" ) type noCopy struct{} @@ -74,13 +75,24 @@ func (t *blocks[T]) GetAuto() (b []T, e error) { } } +type FlexBlocksI[T any] interface { + // // eg + // + // if tmpbuf, putBack, e := buf.Get(); e == nil { + // tmpbuf = append(tmpbuf[:0], b...) + // // do something with tmpbuf + // putBack(tmpbuf) + // } + Get() ([]T, func([]T), error) +} + type flexBlocks[T any] struct { _ noCopy free chan int buf [][]T } -func NewFlexBlocks[T any](blockNum int) BlocksI[T] { +func NewFlexBlocks[T any](blockNum int) FlexBlocksI[T] { p := &flexBlocks[T]{ free: make(chan int, blockNum+1), buf: make([][]T, blockNum), @@ -91,26 +103,43 @@ func NewFlexBlocks[T any](blockNum int) BlocksI[T] { return p } -func (t *flexBlocks[T]) Get() ([]T, func(), error) { +func (t *flexBlocks[T]) Get() ([]T, func([]T), error) { select { case offset := <-t.free: - return t.buf[offset], func() { + return t.buf[offset], func(ts []T) { + t.buf[offset] = ts t.free <- offset }, nil default: - return nil, func() {}, ErrOverflow + return nil, func(_ []T) {}, ErrOverflow } } -func (t *flexBlocks[T]) GetAuto() (b []T, e error) { - select { - case offset := <-t.free: - b = t.buf[offset] - runtime.AddCleanup(&b, func(offset int) { - t.free <- offset - }, offset) - return - default: - return nil, ErrOverflow +type PoolBlocksI[T any] interface { + // // eg + // + // if tmpbuf, putBack, e := buf.Get(); e == nil { + // tmpbuf = append(tmpbuf[:0], b...) + // // do something with tmpbuf + // putBack(tmpbuf) + // } + Get() ([]T, func([]T), error) +} + +type poolBlocks[T any] struct { + pool sync.Pool +} + +func NewPoolBlocks[T any]() PoolBlocksI[T] { + t := &poolBlocks[T]{} + t.pool.New = func() any { + return []T{} } + return t +} + +func (t *poolBlocks[T]) Get() ([]T, func([]T), error) { + return t.pool.Get().([]T), func(ts []T) { + t.pool.Put(ts) + }, nil } diff --git a/slice/Blocks_norace_test.go b/slice/Blocks_norace_test.go new file mode 100644 index 0000000..171c965 --- /dev/null +++ b/slice/Blocks_norace_test.go @@ -0,0 +1,30 @@ +//go:build !race + +package part + +import ( + "runtime/debug" + "testing" +) + +func TestMain3(t *testing.T) { + defer debug.SetGCPercent(debug.SetGCPercent(-1)) + buf := NewPoolBlocks[byte]() + if tmpbuf, putBack, e := buf.Get(); e == nil { + tmpbuf = append(tmpbuf[:0], []byte("123")...) + // do something with tmpbuf + putBack(tmpbuf) + } else { + t.Fail() + } + if tmpbuf, putBack, e := buf.Get(); e == nil { + if cap(tmpbuf) != 8 { + t.Fatal() + } + tmpbuf = append(tmpbuf[:0], []byte("123")...) + // do something with tmpbuf + putBack(tmpbuf) + } else { + t.Fail() + } +} diff --git a/slice/Blocks_test.go b/slice/Blocks_test.go index 1df7f2b..cd0332d 100644 --- a/slice/Blocks_test.go +++ b/slice/Blocks_test.go @@ -4,6 +4,27 @@ import ( "testing" ) +func TestMain4(t *testing.T) { + buf := NewFlexBlocks[byte](1) + if tmpbuf, putBack, e := buf.Get(); e == nil { + tmpbuf = append(tmpbuf[:0], []byte("123")...) + // do something with tmpbuf + putBack(tmpbuf) + } else { + t.Fail() + } + if tmpbuf, putBack, e := buf.Get(); e == nil { + if cap(tmpbuf) != 8 { + t.Fatal() + } + tmpbuf = append(tmpbuf[:0], []byte("123")...) + // do something with tmpbuf + putBack(tmpbuf) + } else { + t.Fail() + } +} + func TestMain(t *testing.T) { buf := NewBlocks[byte](1024, 1) if tmpbuf, putBack, e := buf.Get(); e == nil { diff --git a/tmplKV/tmplK.go b/tmplKV/tmplK.go index f0530bf..8e62f68 100644 --- a/tmplKV/tmplK.go +++ b/tmplKV/tmplK.go @@ -12,7 +12,7 @@ type tmplK struct { SumInDruation int64 Druation int64 now int64 - pool *idpool.Idpool + pool *idpool.Idpool[struct{}] kvt_map syncmap.Map slowBackList *list.List } @@ -20,7 +20,7 @@ type tmplK struct { type tmplK_item struct { kv uintptr kt int64 - uid *idpool.Id + uid *idpool.Id[struct{}] } func New_tmplK(SumInDruation, Druation int64) *tmplK { @@ -28,7 +28,7 @@ func New_tmplK(SumInDruation, Druation int64) *tmplK { s := &tmplK{ SumInDruation: SumInDruation, Druation: Druation, - pool: idpool.New(func() interface{} { return new(struct{}) }), + pool: idpool.New(func() *struct{} { return new(struct{}) }), slowBackList: list.New(), } go func() { @@ -94,15 +94,15 @@ func (s *tmplK) Len() (int64, int) { } func (s *tmplK) freeLen() int64 { - return int64(int(s.pool.Len()) + s.slowBackList.Len()) + return int64(int(s.pool.InUse()) + s.slowBackList.Len()) } -func (s *tmplK) free(i *idpool.Id) { +func (s *tmplK) free(i *idpool.Id[struct{}]) { s.slowBackList.PushBack(i) if s.freeLen() > s.SumInDruation { if el := s.slowBackList.Front(); el != nil && el.Value != nil { e := s.slowBackList.Remove(el) - s.pool.Put(e.(*idpool.Id)) + s.pool.Put(e.(*idpool.Id[struct{}])) } } } diff --git a/tmplKV/tmplV.go b/tmplKV/tmplV.go index 76d9634..f980f4e 100644 --- a/tmplKV/tmplV.go +++ b/tmplKV/tmplV.go @@ -12,7 +12,7 @@ type tmplV struct { Druation int64 now int64 deleteNum int - pool *idpool.Idpool + pool *idpool.Idpool[struct{}] kvt_map map[uintptr]tmplV_item sync.RWMutex } @@ -20,7 +20,7 @@ type tmplV struct { type tmplV_item struct { kv string kt int64 - uid *idpool.Id + uid *idpool.Id[struct{}] } func New_tmplV(SumInDruation, Druation int64) *tmplV { @@ -29,7 +29,7 @@ func New_tmplV(SumInDruation, Druation int64) *tmplV { SumInDruation: SumInDruation, Druation: Druation, kvt_map: make(map[uintptr]tmplV_item), - pool: idpool.New(func() interface{} { return new(struct{}) }), + pool: idpool.New(func() *struct{} { return new(struct{}) }), } go func() { ticker := time.NewTicker(time.Second) @@ -43,7 +43,7 @@ func New_tmplV(SumInDruation, Druation int64) *tmplV { func (s *tmplV) Set(contect string) (key uintptr) { - if s.SumInDruation >= 0 && s.pool.Len() >= s.SumInDruation { //不为无限&&达到限额 随机替代 + if s.SumInDruation >= 0 && s.pool.InUse() >= s.SumInDruation { //不为无限&&达到限额 随机替代 s.Lock() for key, item := range s.kvt_map { s.kvt_map[key] = tmplV_item{ diff --git a/websocket/Client.go b/websocket/Client.go index 0082dbb..f99c970 100644 --- a/websocket/Client.go +++ b/websocket/Client.go @@ -173,7 +173,7 @@ func (o *Client) Handle() (*msgq.MsgType[*WsMsg], error) { Type: websocket.PongMessage, Msg: func(f func([]byte) error) error { f(tmpbuf) - putBack() + putBack(tmpbuf) return nil }, }) @@ -194,7 +194,7 @@ func (o *Client) Handle() (*msgq.MsgType[*WsMsg], error) { Type: websocket.TextMessage, Msg: func(f func([]byte) error) error { f(tmpbuf) - putBack() + putBack(tmpbuf) return nil }, }) diff --git a/websocket/Server.go b/websocket/Server.go index 8d7b99a..aa3abb3 100644 --- a/websocket/Server.go +++ b/websocket/Server.go @@ -13,7 +13,7 @@ import ( type Server struct { ws_mq *mq.Msgq - userpool *idpool.Idpool + userpool *idpool.Idpool[struct{}] m sync.Mutex } @@ -29,8 +29,8 @@ type uinterface struct { //内部消息 func New_server() *Server { return &Server{ - ws_mq: mq.New(), //收发通道 - userpool: idpool.New(func() interface{} { return new(struct{}) }), //浏览器标签页池 + ws_mq: mq.New(), //收发通道 + userpool: idpool.New(func() *struct{} { return new(struct{}) }), //浏览器标签页池 } } @@ -157,5 +157,5 @@ func (t *Server) Interface() *mq.Msgq { } func (t *Server) Len() int64 { - return t.userpool.Len() + return t.userpool.InUse() }