mirror of
https://github.com/fumiama/orbyte.git
synced 2026-06-28 07:50:32 +08:00
optimize: change Destroy -> ManualDestroy
This commit is contained in:
7
item.go
7
item.go
@@ -104,8 +104,11 @@ func (b *Item[T]) destroybystat(stat status) {
|
|||||||
b.pool.put(b)
|
b.pool.put(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy item and put it back to pool.
|
// ManualDestroy item and put it back to pool.
|
||||||
func (b *Item[T]) Destroy() {
|
//
|
||||||
|
// Calling this method without setting pool.SetManualDestroy(true)
|
||||||
|
// can probably cause panic.
|
||||||
|
func (b *Item[T]) ManualDestroy() {
|
||||||
b.destroybystat(status(atomic.SwapUintptr(
|
b.destroybystat(status(atomic.SwapUintptr(
|
||||||
(*uintptr)(&b.stat), uintptr(destroyedstatus),
|
(*uintptr)(&b.stat), uintptr(destroyedstatus),
|
||||||
)))
|
)))
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func testBuffer(buf *orbyte.Item[bytes.Buffer], t *testing.T) {
|
|||||||
if !bytes.Equal(bufr.Pointer().Bytes(), buf.Pointer().Bytes()) {
|
if !bytes.Equal(bufr.Pointer().Bytes(), buf.Pointer().Bytes()) {
|
||||||
t.Fatal("unexpected")
|
t.Fatal("unexpected")
|
||||||
}
|
}
|
||||||
bufr.Destroy()
|
bufr.ManualDestroy()
|
||||||
|
|
||||||
bufcp = bufcp.Trans()
|
bufcp = bufcp.Trans()
|
||||||
if bufcp.Pointer().Len() != 4096 {
|
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()) {
|
if !bytes.Equal(bufcp.Pointer().Bytes(), buf.Pointer().Bytes()) {
|
||||||
t.Fatal("unexpected")
|
t.Fatal("unexpected")
|
||||||
}
|
}
|
||||||
bufcp.Destroy()
|
bufcp.ManualDestroy()
|
||||||
|
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
|
|||||||
@@ -117,8 +117,3 @@ func (b Bytes) Slice(from, to int) Bytes {
|
|||||||
nb.dat = b.dat[from:to]
|
nb.dat = b.dat[from:to]
|
||||||
return nb
|
return nb
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy please refer to Item.Destroy().
|
|
||||||
func (b Bytes) Destroy() {
|
|
||||||
b.buf.Destroy()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ import (
|
|||||||
"time"
|
"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
|
// TestBytesSlice sometimes fails at first run because
|
||||||
// GC not collecting all unused items.
|
// GC not collecting all unused items.
|
||||||
func TestBytesSlice(t *testing.T) {
|
func TestBytesSlice(t *testing.T) {
|
||||||
@@ -29,7 +36,7 @@ func TestBytesSlice(t *testing.T) {
|
|||||||
t.Log("got:", hex.EncodeToString(x.Bytes()))
|
t.Log("got:", hex.EncodeToString(x.Bytes()))
|
||||||
t.Fatal("index", i, "unexpected")
|
t.Fatal("index", i, "unexpected")
|
||||||
}
|
}
|
||||||
x.Destroy()
|
x.manualDestroy()
|
||||||
// test trans slice
|
// test trans slice
|
||||||
b = b.Trans().SliceFrom(5).SliceTo(i - 5 - 5)
|
b = b.Trans().SliceFrom(5).SliceTo(i - 5 - 5)
|
||||||
if !bytes.Equal(buf[5:i-5], b.Bytes()) {
|
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.Log("got:", hex.EncodeToString(b.Bytes()))
|
||||||
t.Fatal("index", i, "unexpected")
|
t.Fatal("index", i, "unexpected")
|
||||||
}
|
}
|
||||||
b.Destroy()
|
b.manualDestroy()
|
||||||
}
|
}
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
@@ -61,7 +68,7 @@ func TestBytesInvolve(t *testing.T) {
|
|||||||
if !bytes.Equal(b.Bytes(), buf[:i]) {
|
if !bytes.Equal(b.Bytes(), buf[:i]) {
|
||||||
t.Fatal("index", i, "unexpected")
|
t.Fatal("index", i, "unexpected")
|
||||||
}
|
}
|
||||||
b.Destroy()
|
b.manualDestroy()
|
||||||
}
|
}
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
out, in := bufferPool.p.CountItems()
|
out, in := bufferPool.p.CountItems()
|
||||||
@@ -82,7 +89,7 @@ func TestBytesParse(t *testing.T) {
|
|||||||
if !bytes.Equal(b.Bytes(), buf[:i]) {
|
if !bytes.Equal(b.Bytes(), buf[:i]) {
|
||||||
t.Fatal("index", i, "unexpected")
|
t.Fatal("index", i, "unexpected")
|
||||||
}
|
}
|
||||||
b.Destroy()
|
b.manualDestroy()
|
||||||
}
|
}
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
out, in := bufferPool.p.CountItems()
|
out, in := bufferPool.p.CountItems()
|
||||||
@@ -106,7 +113,7 @@ func TestBytesCopy(t *testing.T) {
|
|||||||
if bytes.Equal(b.Bytes(), buf[:i]) {
|
if bytes.Equal(b.Bytes(), buf[:i]) {
|
||||||
t.Fatal("index", i, "unexpected")
|
t.Fatal("index", i, "unexpected")
|
||||||
}
|
}
|
||||||
b.Destroy()
|
b.manualDestroy()
|
||||||
}
|
}
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
out, in := bufferPool.p.CountItems()
|
out, in := bufferPool.p.CountItems()
|
||||||
@@ -134,7 +141,7 @@ func TestBytesTransMultithread(t *testing.T) {
|
|||||||
if !bytes.Equal(refer, buf.Bytes()) {
|
if !bytes.Equal(refer, buf.Bytes()) {
|
||||||
panic("unexpected")
|
panic("unexpected")
|
||||||
}
|
}
|
||||||
buf.Destroy()
|
buf.manualDestroy()
|
||||||
}(buf.Trans())
|
}(buf.Trans())
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
25
pool.go
25
pool.go
@@ -13,7 +13,8 @@ type Pool[T any] struct {
|
|||||||
pool sync.Pool
|
pool sync.Pool
|
||||||
countin int32
|
countin int32
|
||||||
countout int32
|
countout int32
|
||||||
isstrict bool
|
noputbak bool
|
||||||
|
manudstr bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPool make a new pool from custom pooler.
|
// NewPool make a new pool from custom pooler.
|
||||||
@@ -26,11 +27,17 @@ func NewPool[T any](pooler Pooler[T]) *Pool[T] {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStrictMode panic on every misuse.
|
// SetNoPutBack make it panic on every use-after-destroy.
|
||||||
//
|
//
|
||||||
// Enable this to detect coding errors.
|
// Enable this to detect coding errors.
|
||||||
func (pool *Pool[T]) SetStrictMode(on bool) {
|
func (pool *Pool[T]) SetNoPutBack(on bool) {
|
||||||
pool.isstrict = on
|
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() {
|
func (pool *Pool[T]) incin() {
|
||||||
@@ -56,17 +63,21 @@ func (pool *Pool[T]) newempty() *Item[T] {
|
|||||||
}
|
}
|
||||||
item.stat = status(0)
|
item.stat = status(0)
|
||||||
pool.incout()
|
pool.incout()
|
||||||
item.setautodestroy()
|
if !pool.manudstr {
|
||||||
|
item.setautodestroy()
|
||||||
|
}
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *Pool[T]) put(item *Item[T]) {
|
func (pool *Pool[T]) put(item *Item[T]) {
|
||||||
runtime.SetFinalizer(item, nil)
|
if !pool.manudstr {
|
||||||
|
runtime.SetFinalizer(item, nil)
|
||||||
|
}
|
||||||
|
|
||||||
item.stat.setdestroyed(true)
|
item.stat.setdestroyed(true)
|
||||||
item.cfg = nil
|
item.cfg = nil
|
||||||
|
|
||||||
if pool.isstrict {
|
if pool.noputbak {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pool.pool.Put(item)
|
pool.pool.Put(item)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
func TestPool(t *testing.T) {
|
func TestPool(t *testing.T) {
|
||||||
p := NewPool[[]byte](simplepooler{})
|
p := NewPool[[]byte](simplepooler{})
|
||||||
x := p.New(200)
|
x := p.New(200)
|
||||||
x.Destroy()
|
x.ManualDestroy()
|
||||||
out, in := p.CountItems()
|
out, in := p.CountItems()
|
||||||
t.Log("out", out, "in", in)
|
t.Log("out", out, "in", in)
|
||||||
if out != 0 || in != 1 {
|
if out != 0 || in != 1 {
|
||||||
@@ -22,7 +22,7 @@ func TestPool(t *testing.T) {
|
|||||||
if out != 1 || in != 0 {
|
if out != 1 || in != 0 {
|
||||||
t.Fatal("unexpected behavior")
|
t.Fatal("unexpected behavior")
|
||||||
}
|
}
|
||||||
item.Destroy()
|
item.ManualDestroy()
|
||||||
}
|
}
|
||||||
out, in = p.CountItems()
|
out, in = p.CountItems()
|
||||||
t.Log("out", out, "in", in)
|
t.Log("out", out, "in", in)
|
||||||
@@ -53,7 +53,7 @@ func TestPool(t *testing.T) {
|
|||||||
func user(item *Item[[]byte], wg *sync.WaitGroup) {
|
func user(item *Item[[]byte], wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
rand.Read(item.Unwrap())
|
rand.Read(item.Unwrap())
|
||||||
item.Destroy()
|
item.ManualDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func usernodestroy(item *Item[[]byte], wg *sync.WaitGroup) {
|
func usernodestroy(item *Item[[]byte], wg *sync.WaitGroup) {
|
||||||
|
|||||||
Reference in New Issue
Block a user