From: qydysky Date: Thu, 8 May 2025 12:26:15 +0000 (+0800) Subject: 1 (#51) X-Git-Tag: v0.28.20250508122622 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=166f9f0549742879ffeb2619c4e81b2e665a068a;p=part%2F.git 1 (#51) --- diff --git a/slice/Blocks.go b/slice/Blocks.go index bb428f2..b85c4bb 100644 --- a/slice/Blocks.go +++ b/slice/Blocks.go @@ -5,10 +5,16 @@ import ( "runtime" ) +type noCopy struct{} + +func (*noCopy) Lock() {} +func (*noCopy) Unlock() {} + type BlocksI[T any] interface { // // eg // // if tmpbuf, putBack, e := buf.Get(); e == nil { + // tmpbuf = append(tmpbuf[:0], b...) // // do something with tmpbuf // putBack() // } @@ -17,6 +23,7 @@ type BlocksI[T any] interface { // // eg // // if tmpbuf, e := buf.GetAuto(); e == nil { + // tmpbuf = append(tmpbuf[:0], b...) // // do something with tmpbuf // } GetAuto() ([]T, error) @@ -29,11 +36,6 @@ type blocks[T any] struct { buf []T } -type noCopy struct{} - -func (*noCopy) Lock() {} -func (*noCopy) Unlock() {} - var ErrOverflow = errors.New("ErrOverflow") func NewBlocks[T any](blockSize int, blockNum int) BlocksI[T] { @@ -49,11 +51,9 @@ func NewBlocks[T any](blockSize int, blockNum int) BlocksI[T] { } func (t *blocks[T]) Get() ([]T, func(), error) { - t.gc() select { case offset := <-t.free: return t.buf[offset*t.size : (offset+1)*t.size], func() { - clear(t.buf[offset*t.size : (offset+1)*t.size]) t.free <- offset }, nil default: @@ -62,12 +62,10 @@ func (t *blocks[T]) Get() ([]T, func(), error) { } func (t *blocks[T]) GetAuto() (b []T, e error) { - t.gc() select { case offset := <-t.free: b = t.buf[offset*t.size : (offset+1)*t.size] runtime.AddCleanup(&b, func(offset int) { - clear(t.buf[offset*t.size : (offset+1)*t.size]) t.free <- offset }, offset) return @@ -76,8 +74,43 @@ func (t *blocks[T]) GetAuto() (b []T, e error) { } } -func (t *blocks[T]) gc() { - if len(t.free) == 0 { - runtime.GC() +type flexBlocks[T any] struct { + _ noCopy + free chan int + buf [][]T +} + +func NewFlexBlocks[T any](blockNum int) BlocksI[T] { + p := &flexBlocks[T]{ + free: make(chan int, blockNum+1), + buf: make([][]T, blockNum), + } + for i := range blockNum { + p.free <- i + } + return p +} + +func (t *flexBlocks[T]) Get() ([]T, func(), error) { + select { + case offset := <-t.free: + return t.buf[offset], func() { + t.free <- offset + }, nil + default: + return nil, func() {}, 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 } } diff --git a/websocket/Client.go b/websocket/Client.go index 3dceb93..0082dbb 100644 --- a/websocket/Client.go +++ b/websocket/Client.go @@ -154,7 +154,7 @@ func (o *Client) Handle() (*msgq.MsgType[*WsMsg], error) { }() buf := make([]byte, humanize.KByte) - var msgs = pslice.NewBlocks[byte](humanize.KByte, o.BufSize) + var msgs = pslice.NewFlexBlocks[byte](o.BufSize) var err error for err == nil { if e := c.SetReadDeadline(time.Now().Add(time.Duration(o.RTOMs * int(time.Millisecond)))); e != nil {