Documentation ¶
Index ¶
- func FreeAll[T Freer](objs ...T)
- func ReleaseAll[R Ref](refs ...R)
- func Retain[R Ref](r R) R
- func RetainAll[R Ref](refs ...R) []R
- func SwapFree[T Freer](old T, new T) T
- func SwapNoRetain[R Ref](old R, new R) R
- func SwapRetain[R Ref](old R, new R) R
- type Atomic32
- type Atomic64
- type FreeGroup
- type Freer
- type R
- type Ref
- type ShardedVar
- type Var
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Retain ¶
func Retain[R Ref](r R) R
Retain retains and returns a reference.
Usage:
tree.table = Retain(table)
func SwapFree ¶
func SwapFree[T Freer](old T, new T) T
SwapFree frees an old object and returns the new.
Usage:
tbl := table.Clone() ... s.table = SwapFree(s.table, tbl)
func SwapNoRetain ¶
func SwapNoRetain[R Ref](old R, new R) R
SwapNoRetain releases an old reference, and returns a new one.
Usage:
tbl := newTable() ... s.table = SwapNoRetain(s.table, tbl)
func SwapRetain ¶
func SwapRetain[R Ref](old R, new R) R
SwapRetain retains a new reference, releases an old one and returns the new.
Usage:
tbl := table.Clone() defer tbl.Release() ... s.table = SwapRetain(s.table, tbl)
Types ¶
type Atomic32 ¶
type Atomic32 struct {
// contains filtered or unexported fields
}
Atomic32 is an atomic int32 reference counter with a released bit. The reference cannot be acquired if the released bit has been set.
Usage: r := Atomic32{} acquired := r.Acquire() if acquired { return } released := r.Release() if !released { return } free()
func (*Atomic32) Acquire ¶
Acquire increments the refcount and returs true if the reference has been acquired, or false if the reference has been released already.
type Atomic64 ¶
type Atomic64 struct {
// contains filtered or unexported fields
}
Atomic64 is an atomic int64 reference counter with a released bit. The reference cannot be acquired if the released bit has been set.
Usage: r := Atomic64{} acquired := r.Acquire() if acquired { return } released := r.Release() if !released { return } free()
func (*Atomic64) Acquire ¶
Acquire increments the refcount and returs true if the reference has been acquired, or false if the reference has been released already.
type FreeGroup ¶
type FreeGroup interface { // Add an object to the free group. Add(obj Freer) // Free free the group and all objects in it. Free() }
FreeGroup frees objects when the group is freed.
type R ¶
type R[T any] interface { // Refcount returns the number of current references. Refcount() int64 // Acquire tries to increment refcount and returns true, or false if already released. Acquire() bool // Retain increments refcount, panics when count is <= 0. Retain() // Release decrements refcount and releases the object if the count is 0. Release() // Unwrap returns the object or panics if the refcount is 0. Unwrap() T }
R is a generic atomic countable reference. It wraps an object and frees it when refcount reaches 0.
func New ¶
New returns a new reference with refcount 1.
Constructors:
- New returns a new reference.
- NewFree returns a new reference with a free function.
- NewFreer returns a new reference with a custom freer.
- NewNoop returns a new reference without any freer.
- Next returns a child reference with a parent reference as a freer.
- NextRetain returns a child reference and retains the parent.
func Next ¶
Next returns a child reference with a parent reference as a freer. The parent is not retained.
Example:
func parse(buf ref.R[buffer.Buffer]) ref.R[*Event] { event := parseEvent(buf.Unwrap()) return ref.Next(event, buf) }
func NextRetain ¶
NextRetain returns a new reference with a parent reference as a freer, retains the parent.
Example:
func parse(buf ref.R[buffer.Buffer]) ref.R[*Event] { event := parseEvent(buf.Unwrap()) return ref.NextRetain(event, buf) }
type Ref ¶
type Ref interface { // Retain increments refcount, panics when count is <= 0. Retain() // Release decrements refcount and releases the object if the count is 0. Release() }
Ref is a countable reference interface without generics, i.e. R[?].
type ShardedVar ¶
ShardedVar is a sharded atomic non-blocking variable which holds a value reference.
The sharded variable is optimized for high contention scenarios. Internally it uses multiple shards to reduce contention.
Fastrand is used to select a shard on access. The scalability of this approach is not linear, but it is still faster than using a single mutex/atomic.
Benchmarks
cpu: Apple M1 Pro BenchmarkShardedVar-10 68205554 15.27 ns/op 65.50 mops 0 B/op 0 allocs/op BenchmarkShardedVar_Parallel-10 53389885 23.08 ns/op 43.33 mops 0 B/op 0 allocs/op BenchmarkShardedVar_Acquire-10 135650500 8.87 ns/op 112.60 mops 0 B/op 0 allocs/op BenchmarkShardedVar_Acquire_Parallel-10 72185512 17.35 ns/op 57.64 mops 0 B/op 0 allocs/op BenchmarkShardedVar_SetRetain-10 3497930 348.9 ns/op 2.86 mops 160 B/op 1 allocs/op
func NewShardedVar ¶
func NewShardedVar[T any]() ShardedVar[T]
NewShardedVar returns a new concurrent variable.
type Var ¶
type Var[T any] interface { // Acquire acquires, retains and returns a value reference, or false. Acquire() (R[T], bool) // Set sets a value, releases the previous reference. Set(T) // SetRetain sets a value reference, retains the new one and releases the old one. SetRetain(R[T]) // Unset clears the value. Unset() // Unwrap returns the current value. // The method must be externally synchronized. Unwrap() opt.Opt[T] // UnwrapRef returns the current reference. // The method must be externally synchronized. UnwrapRef() opt.Opt[R[T]] }
Var is an atomic non-blocking variable which holds a value reference.
Benchmarks
cpu: Apple M1 Pro BenchmarkVar-10 86551359 13.97 ns/op 71.58 mops 0 B/op 0 allocs/op BenchmarkVar_Parallel-10 7920332 151.00 ns/op 6.62 mops 0 B/op 0 allocs/op BenchmarkVar_SetRetain-10 31419198 37.71 ns/op 26.52 mops 24 B/op 1 allocs/op