--- /dev/null
+package part
+
+import (
+ "sync"
+)
+
+type buf[T any] struct {
+ maxsize int
+ newF func() *T
+ validF func(*T) bool
+ reuseF func(*T) *T
+ buf []*T
+ sync.RWMutex
+}
+
+func New[T any](NewF func() *T, ValidF func(*T) bool, ReuseF func(*T) *T, maxsize int) *buf[T] {
+ t := new(buf[T])
+ t.newF = NewF
+ t.validF = ValidF
+ t.reuseF = ReuseF
+ t.maxsize = maxsize
+ return t
+}
+
+func (t *buf[T]) Trim() {
+ t.Lock()
+ defer t.Unlock()
+
+ for i := 0; i < len(t.buf); i++ {
+ if !t.validF(t.buf[i]) {
+ t.buf[i] = nil
+ t.buf = append(t.buf[:i], t.buf[i:]...)
+ i--
+ }
+ }
+}
+
+func (t *buf[T]) Get() *T {
+ t.Lock()
+ defer t.Unlock()
+
+ for i := 0; i < len(t.buf); i++ {
+ if !t.validF(t.buf[i]) {
+ return t.reuseF(t.buf[i])
+ }
+ }
+
+ return t.newF()
+}
+
+func (t *buf[T]) Put(item ...*T) {
+ if len(item) == 0 {
+ return
+ }
+
+ t.Lock()
+ defer t.Unlock()
+
+ var cu = 0
+ for i := 0; i < len(t.buf); i++ {
+ if !t.validF(t.buf[i]) {
+ t.buf[i] = item[cu]
+ cu++
+ if cu >= len(item) {
+ return
+ }
+ }
+ }
+
+ for i := cu; i < len(item) && t.maxsize > len(t.buf); i++ {
+ t.buf = append(t.buf, item[i])
+ }
+}
--- /dev/null
+package part
+
+import (
+ "testing"
+ "unsafe"
+)
+
+type a struct {
+ d []byte
+ v bool
+}
+
+func TestXxx(t *testing.T) {
+ var newf = func() *a {
+ return &a{v: true}
+ }
+
+ var validf = func(t *a) bool {
+ return t.v
+ }
+
+ var reusef = func(t *a) *a {
+ t.d = t.d[:0]
+ t.v = true
+ return t
+ }
+
+ var b = New(newf, validf, reusef, 10)
+
+ var c1 = b.Get()
+ c1.d = append(c1.d, []byte("1")...)
+
+ t.Log(unsafe.Pointer(c1), c1)
+
+ var c2 = b.Get()
+ c2.d = append(c2.d, []byte("2")...)
+
+ t.Log(unsafe.Pointer(c2), c2)
+
+ b.Put(c1)
+
+ t.Log(unsafe.Pointer(c1), c1)
+
+ c1.v = false
+
+ t.Log(unsafe.Pointer(c1), c1)
+
+ var c3 = b.Get()
+
+ t.Log(unsafe.Pointer(c3), c3)
+
+}
--- /dev/null
+package part
+
+import (
+ "errors"
+ "sync"
+ "unsafe"
+)
+
+type buf[T any] struct {
+ maxsize int
+ bufsize int
+ modified Modified
+ buf []T
+ sync.RWMutex
+}
+
+type Modified struct {
+ p uintptr
+ t uint64
+}
+
+func New[T any](maxsize ...int) *buf[T] {
+ t := new(buf[T])
+ if len(maxsize) > 0 {
+ t.maxsize = maxsize[0]
+ }
+ t.modified.p = uintptr(unsafe.Pointer(t))
+ return t
+}
+
+func (t *buf[T]) Clear() {
+ t.Lock()
+ defer t.Unlock()
+ t.buf = nil
+ t.bufsize = 0
+ t.modified.t += 1
+}
+
+func (t *buf[T]) Size() int {
+ t.RLock()
+ defer t.RUnlock()
+
+ return t.bufsize
+}
+
+func (t *buf[T]) IsEmpty() bool {
+ t.RLock()
+ defer t.RUnlock()
+
+ return t.bufsize == 0
+}
+
+func (t *buf[T]) Reset() {
+ t.Lock()
+ defer t.Unlock()
+
+ t.bufsize = 0
+ t.modified.t += 1
+}
+
+func (t *buf[T]) Append(data []T) error {
+ t.Lock()
+ defer t.Unlock()
+
+ if len(t.buf)+len(data) > t.maxsize {
+ return errors.New("超出设定maxsize")
+ } else if len(t.buf) == 0 {
+ if t.maxsize == 0 {
+ t.buf = make([]T, len(data))
+ } else {
+ t.buf = make([]T, len(data), t.maxsize)
+ }
+ } else {
+ diff := len(t.buf) - t.bufsize - len(data)
+ if diff < 0 {
+ t.buf = append(t.buf, make([]T, -diff)...)
+ } else {
+ t.buf = t.buf[:t.bufsize+len(data)]
+ }
+ }
+ t.bufsize += copy(t.buf[t.bufsize:], data)
+ t.modified.t += 1
+ return nil
+}
+
+func (t *buf[T]) RemoveFront(n int) error {
+ if n <= 0 {
+ return nil
+ }
+
+ t.Lock()
+ defer t.Unlock()
+
+ if t.bufsize < n {
+ return errors.New("尝试移除的数值大于长度")
+ } else if t.bufsize == n {
+ t.bufsize = 0
+ } else {
+ t.bufsize = copy(t.buf, t.buf[n:t.bufsize])
+ }
+
+ t.modified.t += 1
+ return nil
+}
+
+func (t *buf[T]) RemoveBack(n int) error {
+ if n <= 0 {
+ return nil
+ }
+
+ t.Lock()
+ defer t.Unlock()
+
+ if t.bufsize < n {
+ return errors.New("尝试移除的数值大于长度")
+ } else if t.bufsize == n {
+ t.bufsize = 0
+ } else {
+ t.bufsize -= n
+ }
+
+ t.modified.t += 1
+ return nil
+}
+
+// unsafe
+func (t *buf[T]) SetModified() {
+ t.Lock()
+ defer t.Unlock()
+
+ t.modified.t += 1
+}
+
+func (t *buf[T]) GetModified() Modified {
+ t.RLock()
+ defer t.RUnlock()
+
+ return t.modified
+}
+
+func (t *buf[T]) HadModified(mt Modified) (same bool, err error) {
+ t.RLock()
+ defer t.RUnlock()
+
+ if t.modified.p != mt.p {
+ err = errors.New("不能对比不同buf")
+ }
+ same = t.modified.t != mt.t
+ return
+}
+
+// unsafe
+func (t *buf[T]) GetPureBuf() (buf []T) {
+ t.RLock()
+ defer t.RUnlock()
+
+ return t.buf[:t.bufsize]
+}
+
+func (t *buf[T]) GetCopyBuf() (buf []T) {
+ t.RLock()
+ defer t.RUnlock()
+
+ buf = make([]T, t.bufsize)
+ copy(buf, t.buf[:t.bufsize])
+ return
+}
--- /dev/null
+package part
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestXxx(t *testing.T) {
+ var (
+ b = New[byte](5)
+ c = New[byte]()
+ )
+ if !b.IsEmpty() {
+ t.Fatal()
+ }
+ b.Append([]byte("abc"))
+ if b.IsEmpty() || b.Size() != 3 {
+ t.Fatal()
+ }
+ if _, e := b.HadModified(c.GetModified()); e == nil {
+ t.Fatal()
+ }
+ bc := b.GetCopyBuf()
+ bt := b.GetModified()
+ b.RemoveFront(1)
+ if b.IsEmpty() || b.Size() != 2 || !bytes.Equal(bc, []byte("abc")) ||
+ !bytes.Equal(b.GetPureBuf(), []byte("bc")) || bt == b.GetModified() {
+ t.Fatal()
+ }
+ b.RemoveBack(1)
+ if b.IsEmpty() || b.Size() != 1 || !bytes.Equal(bc, []byte("abc")) || !bytes.Equal(b.GetPureBuf(), []byte("b")) {
+ t.Fatal()
+ }
+ b.Reset()
+ if !b.IsEmpty() || b.Size() != 0 || !bytes.Equal(bc, []byte("abc")) || !bytes.Equal(b.GetPureBuf(), []byte("")) {
+ t.Fatal()
+ }
+ if e := b.RemoveFront(1); e == nil || e.Error() != "尝试移除的数值大于长度" {
+ t.Fatal()
+ }
+ if e := b.Append([]byte("abcdef")); e == nil || e.Error() != "超出设定maxsize" {
+ t.Fatal()
+ }
+ b.Clear()
+ if !b.IsEmpty() || b.Size() != 0 {
+ t.Fatal()
+ }
+ b.Append([]byte("abc"))
+ if b.IsEmpty() || b.Size() != 3 {
+ t.Fatal()
+ }
+}