mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-15 12:03:00 -06:00
[performance] update go-structr and go-mutexes with memory usage improvements (#2909)
* update go-structr and go-mutexes with memory usage improvements * bump to go-structr v0.8.4
This commit is contained in:
parent
578a4e0cf5
commit
c06e6fb656
26 changed files with 1409 additions and 163 deletions
99
vendor/codeberg.org/gruf/go-mempool/pool.go
generated
vendored
Normal file
99
vendor/codeberg.org/gruf/go-mempool/pool.go
generated
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
package mempool
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const DefaultDirtyFactor = 128
|
||||
|
||||
// Pool provides a type-safe form
|
||||
// of UnsafePool using generics.
|
||||
//
|
||||
// Note it is NOT safe for concurrent
|
||||
// use, you must protect it yourself!
|
||||
type Pool[T any] struct {
|
||||
|
||||
// New is an optionally provided
|
||||
// allocator used when no value
|
||||
// is available for use in pool.
|
||||
New func() T
|
||||
|
||||
// Reset is an optionally provided
|
||||
// value resetting function called
|
||||
// on passed value to Put().
|
||||
Reset func(T)
|
||||
|
||||
UnsafePool
|
||||
}
|
||||
|
||||
func (p *Pool[T]) Get() T {
|
||||
if ptr := p.UnsafePool.Get(); ptr != nil {
|
||||
return *(*T)(ptr)
|
||||
} else if p.New != nil {
|
||||
return p.New()
|
||||
}
|
||||
var z T
|
||||
return z
|
||||
}
|
||||
|
||||
func (p *Pool[T]) Put(t T) {
|
||||
if p.Reset != nil {
|
||||
p.Reset(t)
|
||||
}
|
||||
ptr := unsafe.Pointer(&t)
|
||||
p.UnsafePool.Put(ptr)
|
||||
}
|
||||
|
||||
// UnsafePool provides an incredibly
|
||||
// simple memory pool implementation
|
||||
// that stores ptrs to memory values,
|
||||
// and regularly flushes internal pool
|
||||
// structures according to DirtyFactor.
|
||||
//
|
||||
// Note it is NOT safe for concurrent
|
||||
// use, you must protect it yourself!
|
||||
type UnsafePool struct {
|
||||
|
||||
// DirtyFactor determines the max
|
||||
// number of $dirty count before
|
||||
// pool is garbage collected. Where:
|
||||
// $dirty = len(current) - len(victim)
|
||||
DirtyFactor int
|
||||
|
||||
current []unsafe.Pointer
|
||||
victim []unsafe.Pointer
|
||||
}
|
||||
|
||||
func (p *UnsafePool) Get() unsafe.Pointer {
|
||||
// First try current list.
|
||||
if len(p.current) > 0 {
|
||||
ptr := p.current[len(p.current)-1]
|
||||
p.current = p.current[:len(p.current)-1]
|
||||
return ptr
|
||||
}
|
||||
|
||||
// Fallback to victim.
|
||||
if len(p.victim) > 0 {
|
||||
ptr := p.victim[len(p.victim)-1]
|
||||
p.victim = p.victim[:len(p.victim)-1]
|
||||
return ptr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UnsafePool) Put(ptr unsafe.Pointer) {
|
||||
p.current = append(p.current, ptr)
|
||||
|
||||
// Get dirty factor.
|
||||
df := p.DirtyFactor
|
||||
if df == 0 {
|
||||
df = DefaultDirtyFactor
|
||||
}
|
||||
|
||||
if len(p.current)-len(p.victim) > df {
|
||||
// Garbage collection!
|
||||
p.victim = p.current
|
||||
p.current = nil
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue