]> 127.0.0.1 Git - part/.git/commitdiff
1 v0.28.20240812121228
authorqydysky <qydysky@foxmail.com>
Mon, 12 Aug 2024 12:06:40 +0000 (20:06 +0800)
committerqydysky <qydysky@foxmail.com>
Mon, 12 Aug 2024 12:06:40 +0000 (20:06 +0800)
slice/Buf.go [new file with mode: 0644]
slice/Buf_test.go [new file with mode: 0644]

diff --git a/slice/Buf.go b/slice/Buf.go
new file mode 100644 (file)
index 0000000..c0549ed
--- /dev/null
@@ -0,0 +1,48 @@
+package part
+
+import (
+       "runtime"
+       "sync/atomic"
+)
+
+type BufI[T any] interface {
+       // // eg
+       //
+       //      if tmpbuf, e := buf.Get(); e == nil {
+       //              // do something with tmpbuf
+       //      }
+       Get() []T
+       CacheCount() int64
+}
+
+type bufs[T any] struct {
+       _   noCopy
+       num atomic.Int64
+       buf [][]T
+}
+
+func NewBufs[T any]() BufI[T] {
+       return &bufs[T]{
+               buf: [][]T{},
+       }
+}
+
+func (t *bufs[T]) Get() (b []T) {
+       if len(t.buf) > 0 {
+               b = t.buf[0][:0]
+               t.buf = t.buf[:copy(t.buf, t.buf[1:])]
+               t.num.Add(-1)
+               return
+       } else {
+               b = []T{}
+       }
+       runtime.SetFinalizer(&b, func(objp any) {
+               t.buf = append(t.buf, *objp.(*[]T))
+               t.num.Add(1)
+       })
+       return
+}
+
+func (t *bufs[T]) CacheCount() int64 {
+       return t.num.Load()
+}
diff --git a/slice/Buf_test.go b/slice/Buf_test.go
new file mode 100644 (file)
index 0000000..260739c
--- /dev/null
@@ -0,0 +1,34 @@
+package part
+
+import (
+       "runtime"
+       "testing"
+       "time"
+)
+
+func TestBuf(t *testing.T) {
+       bu := NewBufs[byte]()
+       allocs(bu.Get())
+       runtime.GC()
+       time.Sleep(time.Second)
+       if bu.CacheCount() != 1 {
+               t.Fatal()
+       }
+       b := allocs(bu.Get())
+       runtime.GC()
+       time.Sleep(time.Second)
+       if bu.CacheCount() != 0 {
+               t.Fatal()
+       }
+       allocs(bu.Get())
+       runtime.GC()
+       time.Sleep(time.Second)
+       t.Log(b, bu.CacheCount())
+       if bu.CacheCount() != 1 {
+               t.Fatal()
+       }
+}
+
+func allocs(b []byte) []byte {
+       return append(b, 0x01)
+}