From 0e26d48d6e9e6d51a70a756e9c20a0c91c417a59 Mon Sep 17 00:00:00 2001 From: qydysky Date: Mon, 12 Aug 2024 20:06:40 +0800 Subject: [PATCH] 1 --- slice/Buf.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++ slice/Buf_test.go | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 slice/Buf.go create mode 100644 slice/Buf_test.go diff --git a/slice/Buf.go b/slice/Buf.go new file mode 100644 index 0000000..c0549ed --- /dev/null +++ b/slice/Buf.go @@ -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 index 0000000..260739c --- /dev/null +++ b/slice/Buf_test.go @@ -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) +} -- 2.39.2