]> 127.0.0.1 Git - part/.git/commitdiff
1 (#53) v0.28.20250511190336
authorqydysky <qydysky@foxmail.com>
Sun, 11 May 2025 19:03:28 +0000 (03:03 +0800)
committerGitHub <noreply@github.com>
Sun, 11 May 2025 19:03:28 +0000 (03:03 +0800)
* 1

* 1

* 1

* 1

.github/workflows/test1.yml
idpool/Idpool.go
idpool/Idpool_test.go
slice/Blocks.go
slice/Blocks_norace_test.go [new file with mode: 0644]
slice/Blocks_test.go
tmplKV/tmplK.go
tmplKV/tmplV.go
websocket/Client.go
websocket/Server.go

index a32c866f1ef5418049a8ffee0ae23a292c702862..ccd425edaccbc09021d2be4ffd16c573fc8de7b7 100644 (file)
@@ -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/...
index df46ca741098a5e6c96f2471773d6b939997759b..7367ca53d20b927d6b17cd1d39cf1f82fc48bf2d 100644 (file)
@@ -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)
 }
index 11dabbbc6add9c68acc9c8abe8a2195a89fc2827..ed360f39f5634edee9cec7ef4bc4721cb9a10b81 100644 (file)
@@ -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()
+       }
 }
index b85c4bb8d7de2cee339c166176acf20100a9cfa1..8faf792869bcb573aa08745627b3d184a9fd2a72 100644 (file)
@@ -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 (file)
index 0000000..171c965
--- /dev/null
@@ -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()
+       }
+}
index 1df7f2b1d106ff83f5e2107ea0ada64e11247f90..cd0332d5f3e79c77c95464eb8d371017c80ae8a5 100644 (file)
@@ -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 {
index f0530bf4ec56fab6f42eb7626dcc62d8376370d7..8e62f68fb3a8c779412fbf59883e18d5cec2e2a5 100644 (file)
@@ -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{}]))
                }
        }
 }
index 76d963481af9fd244cb44f07f2b2b059c0b0ff91..f980f4e1eca1dc11c5a94e0ee464f84bd0442af3 100644 (file)
@@ -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{
index 0082dbb83df5b7499becb7787c4704a161fdf6b7..f99c970ff6f022978b1b6781ce946fbae1bbb272 100644 (file)
@@ -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
                                                },
                                        })
index 8d7b99aeeaf237d492ffe49eaf136766860873be..aa3abb373c60ee21b46bd15af55400635dacf5f5 100644 (file)
@@ -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()
 }