1
0
mirror of https://github.com/fumiama/orbyte.git synced 2026-06-09 12:40:34 +08:00

optimize: change Destroy -> ManualDestroy

This commit is contained in:
源文雨
2025-02-25 19:35:43 +09:00
parent 343a5d57be
commit 4a462a1437
6 changed files with 41 additions and 25 deletions

View File

@@ -104,8 +104,11 @@ func (b *Item[T]) destroybystat(stat status) {
b.pool.put(b)
}
// Destroy item and put it back to pool.
func (b *Item[T]) Destroy() {
// ManualDestroy item and put it back to pool.
//
// Calling this method without setting pool.SetManualDestroy(true)
// can probably cause panic.
func (b *Item[T]) ManualDestroy() {
b.destroybystat(status(atomic.SwapUintptr(
(*uintptr)(&b.stat), uintptr(destroyedstatus),
)))

View File

@@ -42,7 +42,7 @@ func testBuffer(buf *orbyte.Item[bytes.Buffer], t *testing.T) {
if !bytes.Equal(bufr.Pointer().Bytes(), buf.Pointer().Bytes()) {
t.Fatal("unexpected")
}
bufr.Destroy()
bufr.ManualDestroy()
bufcp = bufcp.Trans()
if bufcp.Pointer().Len() != 4096 {
@@ -51,7 +51,7 @@ func testBuffer(buf *orbyte.Item[bytes.Buffer], t *testing.T) {
if !bytes.Equal(bufcp.Pointer().Bytes(), buf.Pointer().Bytes()) {
t.Fatal("unexpected")
}
bufcp.Destroy()
bufcp.ManualDestroy()
runtime.GC()
runtime.Gosched()

View File

@@ -117,8 +117,3 @@ func (b Bytes) Slice(from, to int) Bytes {
nb.dat = b.dat[from:to]
return nb
}
// Destroy please refer to Item.Destroy().
func (b Bytes) Destroy() {
b.buf.Destroy()
}

View File

@@ -11,6 +11,13 @@ import (
"time"
)
// manualDestroy please refer to Item.manualDestroy().
//
// Only for test purposes.
func (b Bytes) manualDestroy() {
b.buf.ManualDestroy()
}
// TestBytesSlice sometimes fails at first run because
// GC not collecting all unused items.
func TestBytesSlice(t *testing.T) {
@@ -29,7 +36,7 @@ func TestBytesSlice(t *testing.T) {
t.Log("got:", hex.EncodeToString(x.Bytes()))
t.Fatal("index", i, "unexpected")
}
x.Destroy()
x.manualDestroy()
// test trans slice
b = b.Trans().SliceFrom(5).SliceTo(i - 5 - 5)
if !bytes.Equal(buf[5:i-5], b.Bytes()) {
@@ -37,7 +44,7 @@ func TestBytesSlice(t *testing.T) {
t.Log("got:", hex.EncodeToString(b.Bytes()))
t.Fatal("index", i, "unexpected")
}
b.Destroy()
b.manualDestroy()
}
runtime.GC()
runtime.Gosched()
@@ -61,7 +68,7 @@ func TestBytesInvolve(t *testing.T) {
if !bytes.Equal(b.Bytes(), buf[:i]) {
t.Fatal("index", i, "unexpected")
}
b.Destroy()
b.manualDestroy()
}
runtime.GC()
out, in := bufferPool.p.CountItems()
@@ -82,7 +89,7 @@ func TestBytesParse(t *testing.T) {
if !bytes.Equal(b.Bytes(), buf[:i]) {
t.Fatal("index", i, "unexpected")
}
b.Destroy()
b.manualDestroy()
}
runtime.GC()
out, in := bufferPool.p.CountItems()
@@ -106,7 +113,7 @@ func TestBytesCopy(t *testing.T) {
if bytes.Equal(b.Bytes(), buf[:i]) {
t.Fatal("index", i, "unexpected")
}
b.Destroy()
b.manualDestroy()
}
runtime.GC()
out, in := bufferPool.p.CountItems()
@@ -134,7 +141,7 @@ func TestBytesTransMultithread(t *testing.T) {
if !bytes.Equal(refer, buf.Bytes()) {
panic("unexpected")
}
buf.Destroy()
buf.manualDestroy()
}(buf.Trans())
}()
}

25
pool.go
View File

@@ -13,7 +13,8 @@ type Pool[T any] struct {
pool sync.Pool
countin int32
countout int32
isstrict bool
noputbak bool
manudstr bool
}
// NewPool make a new pool from custom pooler.
@@ -26,11 +27,17 @@ func NewPool[T any](pooler Pooler[T]) *Pool[T] {
return p
}
// SetStrictMode panic on every misuse.
// SetNoPutBack make it panic on every use-after-destroy.
//
// Enable this to detect coding errors.
func (pool *Pool[T]) SetStrictMode(on bool) {
pool.isstrict = on
func (pool *Pool[T]) SetNoPutBack(on bool) {
pool.noputbak = on
}
// SetManualDestroy mark that user must manually
// run Item.Destroy().
func (pool *Pool[T]) SetManualDestroy(on bool) {
pool.manudstr = on
}
func (pool *Pool[T]) incin() {
@@ -56,17 +63,21 @@ func (pool *Pool[T]) newempty() *Item[T] {
}
item.stat = status(0)
pool.incout()
item.setautodestroy()
if !pool.manudstr {
item.setautodestroy()
}
return item
}
func (pool *Pool[T]) put(item *Item[T]) {
runtime.SetFinalizer(item, nil)
if !pool.manudstr {
runtime.SetFinalizer(item, nil)
}
item.stat.setdestroyed(true)
item.cfg = nil
if pool.isstrict {
if pool.noputbak {
return
}
pool.pool.Put(item)

View File

@@ -10,7 +10,7 @@ import (
func TestPool(t *testing.T) {
p := NewPool[[]byte](simplepooler{})
x := p.New(200)
x.Destroy()
x.ManualDestroy()
out, in := p.CountItems()
t.Log("out", out, "in", in)
if out != 0 || in != 1 {
@@ -22,7 +22,7 @@ func TestPool(t *testing.T) {
if out != 1 || in != 0 {
t.Fatal("unexpected behavior")
}
item.Destroy()
item.ManualDestroy()
}
out, in = p.CountItems()
t.Log("out", out, "in", in)
@@ -53,7 +53,7 @@ func TestPool(t *testing.T) {
func user(item *Item[[]byte], wg *sync.WaitGroup) {
defer wg.Done()
rand.Read(item.Unwrap())
item.Destroy()
item.ManualDestroy()
}
func usernodestroy(item *Item[[]byte], wg *sync.WaitGroup) {