diff --git a/.golangci.yml b/.golangci.yml index 96a74a4..07a3a0f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,6 +2,9 @@ linters-settings: errcheck: ignore: fmt:.*,io/ioutil:^Read.* ignoretests: true + exclude-functions: + - (*github.com/fumiama/orbyte.Item).V + - (*github.com/fumiama/orbyte.Item).P goimports: local-prefixes: github.com/fumiama/orbyte diff --git a/item.go b/item.go index 0fd12d1..dcc3b4a 100644 --- a/item.go +++ b/item.go @@ -25,6 +25,13 @@ type Item[T any] struct { val T } +// Ignore marks Item to be independent and will not be +// put back. +func (b *Item[T]) Ignore() *Item[T] { + b.stat.setignored(true) + return b +} + // Trans disable inner val being reset by // destroy and return a safe copy of val. // @@ -69,7 +76,7 @@ func (b *Item[T]) HasInvolved() bool { // V use value of the item. // // This operation is safe in function f. -func (b *Item[T]) V(f func(T)) { +func (b *Item[T]) V(f func(T)) *Item[T] { if b.stat.hasdestroyed() { panic("use after destroy") } @@ -82,12 +89,13 @@ func (b *Item[T]) V(f func(T)) { } f(b.val) runtime.KeepAlive(b) + return b } // P use pointer value of the item. // // This operation is safe in function f. -func (b *Item[T]) P(f func(*T)) { +func (b *Item[T]) P(f func(*T)) *Item[T] { if b.stat.hasdestroyed() { panic("use after destroy") } @@ -100,6 +108,7 @@ func (b *Item[T]) P(f func(*T)) { } f(&b.val) runtime.KeepAlive(b) + return b } // Copy data completely with separated ownership. @@ -129,6 +138,11 @@ func (b *Item[T]) destroybystat(stat status) { var v T b.val = v } + if stat.hasignored() { // ignore put + runtime.SetFinalizer(b, nil) + b.cfg = nil + return + } b.pool.put(b) } diff --git a/pbuf/bytes.go b/pbuf/bytes.go index 2222d8d..6a13dad 100644 --- a/pbuf/bytes.go +++ b/pbuf/bytes.go @@ -44,6 +44,16 @@ func (bufferPool BufferPool[USRDAT]) NewBytes(sz int) (b UserBytes[USRDAT]) { return } +// NewLargeBytes alloc sz bytes without involving. +func (bufferPool BufferPool[USRDAT]) NewLargeBytes(sz int) (b UserBytes[USRDAT]) { + buf := bufferPool.New(sz).Ignore() + b.buf = buf + buf.P(func(buf *UserBuffer[USRDAT]) { + b.b = buf.Len() + }) + return +} + // InvolveBytes involve outside buf into pool. func (bufferPool BufferPool[USRDAT]) InvolveBytes(p ...byte) (b UserBytes[USRDAT]) { buf := bufferPool.Involve(len(p), bytes.NewBuffer(p)) diff --git a/status.go b/status.go index bebd0f4..bd26313 100644 --- a/status.go +++ b/status.go @@ -11,6 +11,7 @@ const ( statusisbuffered = 1 << iota statusdestroyed statusinsyncop + statushasignored ) type status uintptr @@ -96,3 +97,11 @@ func (c *status) setdestroyed(v bool) { func (c *status) setinsyncop(v bool) bool { return c.setboolunique(v, statusinsyncop) } + +func (c *status) hasignored() bool { + return c.loadbool(statushasignored) +} + +func (c *status) setignored(v bool) { + c.setbool(v, statushasignored) +}