summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go215
1 files changed, 0 insertions, 215 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go
deleted file mode 100644
index d67a3262d..000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go
+++ /dev/null
@@ -1,215 +0,0 @@
-package wazevoapi
-
-const poolPageSize = 128
-
-// Pool is a pool of T that can be allocated and reset.
-// This is useful to avoid unnecessary allocations.
-type Pool[T any] struct {
- pages []*[poolPageSize]T
- resetFn func(*T)
- allocated, index int
-}
-
-// NewPool returns a new Pool.
-// resetFn is called when a new T is allocated in Pool.Allocate.
-func NewPool[T any](resetFn func(*T)) Pool[T] {
- var ret Pool[T]
- ret.resetFn = resetFn
- ret.Reset()
- return ret
-}
-
-// Allocated returns the number of allocated T currently in the pool.
-func (p *Pool[T]) Allocated() int {
- return p.allocated
-}
-
-// Allocate allocates a new T from the pool.
-func (p *Pool[T]) Allocate() *T {
- if p.index == poolPageSize {
- if len(p.pages) == cap(p.pages) {
- p.pages = append(p.pages, new([poolPageSize]T))
- } else {
- i := len(p.pages)
- p.pages = p.pages[:i+1]
- if p.pages[i] == nil {
- p.pages[i] = new([poolPageSize]T)
- }
- }
- p.index = 0
- }
- ret := &p.pages[len(p.pages)-1][p.index]
- if p.resetFn != nil {
- p.resetFn(ret)
- }
- p.index++
- p.allocated++
- return ret
-}
-
-// View returns the pointer to i-th item from the pool.
-func (p *Pool[T]) View(i int) *T {
- page, index := i/poolPageSize, i%poolPageSize
- return &p.pages[page][index]
-}
-
-// Reset resets the pool.
-func (p *Pool[T]) Reset() {
- p.pages = p.pages[:0]
- p.index = poolPageSize
- p.allocated = 0
-}
-
-// IDedPool is a pool of T that can be allocated and reset, with a way to get T by an ID.
-type IDedPool[T any] struct {
- pool Pool[T]
- idToItems []*T
- maxIDEncountered int
-}
-
-// NewIDedPool returns a new IDedPool.
-func NewIDedPool[T any](resetFn func(*T)) IDedPool[T] {
- return IDedPool[T]{pool: NewPool(resetFn), maxIDEncountered: -1}
-}
-
-// GetOrAllocate returns the T with the given id.
-func (p *IDedPool[T]) GetOrAllocate(id int) *T {
- if p.maxIDEncountered < id {
- p.maxIDEncountered = id
- }
- if id >= len(p.idToItems) {
- p.idToItems = append(p.idToItems, make([]*T, id-len(p.idToItems)+1)...)
- }
- if p.idToItems[id] == nil {
- p.idToItems[id] = p.pool.Allocate()
- }
- return p.idToItems[id]
-}
-
-// Get returns the T with the given id, or nil if it's not allocated.
-func (p *IDedPool[T]) Get(id int) *T {
- if id >= len(p.idToItems) {
- return nil
- }
- return p.idToItems[id]
-}
-
-// Reset resets the pool.
-func (p *IDedPool[T]) Reset() {
- p.pool.Reset()
- for i := 0; i <= p.maxIDEncountered; i++ {
- p.idToItems[i] = nil
- }
- p.maxIDEncountered = -1
-}
-
-// MaxIDEncountered returns the maximum id encountered so far.
-func (p *IDedPool[T]) MaxIDEncountered() int {
- return p.maxIDEncountered
-}
-
-// arraySize is the size of the array used in VarLengthPool's arrayPool.
-// This is chosen to be 8, which is empirically a good number among 8, 12, 16 and 20.
-const arraySize = 8
-
-// VarLengthPool is a pool of VarLength[T] that can be allocated and reset.
-type (
- VarLengthPool[T any] struct {
- arrayPool Pool[varLengthPoolArray[T]]
- slicePool Pool[[]T]
- }
- // varLengthPoolArray wraps an array and keeps track of the next index to be used to avoid the heap allocation.
- varLengthPoolArray[T any] struct {
- arr [arraySize]T
- next int
- }
-)
-
-// VarLength is a variable length array that can be reused via a pool.
-type VarLength[T any] struct {
- arr *varLengthPoolArray[T]
- slc *[]T
-}
-
-// NewVarLengthPool returns a new VarLengthPool.
-func NewVarLengthPool[T any]() VarLengthPool[T] {
- return VarLengthPool[T]{
- arrayPool: NewPool(func(v *varLengthPoolArray[T]) {
- v.next = 0
- }),
- slicePool: NewPool(func(i *[]T) {
- *i = (*i)[:0]
- }),
- }
-}
-
-// NewNilVarLength returns a new VarLength[T] with a nil backing.
-func NewNilVarLength[T any]() VarLength[T] {
- return VarLength[T]{}
-}
-
-// Allocate allocates a new VarLength[T] from the pool.
-func (p *VarLengthPool[T]) Allocate(knownMin int) VarLength[T] {
- if knownMin <= arraySize {
- arr := p.arrayPool.Allocate()
- return VarLength[T]{arr: arr}
- }
- slc := p.slicePool.Allocate()
- if cap(*slc) < knownMin {
- *slc = make([]T, 0, knownMin)
- }
- return VarLength[T]{slc: slc}
-}
-
-// Reset resets the pool.
-func (p *VarLengthPool[T]) Reset() {
- p.arrayPool.Reset()
- p.slicePool.Reset()
-}
-
-// Append appends items to the backing slice just like the `append` builtin function in Go.
-func (i VarLength[T]) Append(p *VarLengthPool[T], items ...T) VarLength[T] {
- slc := i.slc
- if slc != nil {
- *slc = append(*slc, items...)
- return i
- }
-
- arr := i.arr
- if arr == nil {
- arr = p.arrayPool.Allocate()
- i.arr = arr
- }
-
- if arr.next+len(items) <= arraySize {
- arr.next += copy(arr.arr[arr.next:], items)
- } else {
- slc = p.slicePool.Allocate()
- // Copy the array to the slice.
- *slc = append(*slc, arr.arr[:arr.next]...)
- *slc = append(*slc, items...)
- i.slc = slc
- }
- return i
-}
-
-// View returns the backing slice.
-func (i VarLength[T]) View() []T {
- if slc := i.slc; slc != nil {
- return *i.slc
- }
- if arr := i.arr; arr != nil {
- return arr.arr[:arr.next]
- }
- return nil
-}
-
-// Cut cuts the backing slice to the given length.
-// Precondition: n <= len(i.backing).
-func (i VarLength[T]) Cut(n int) {
- if slc := i.slc; slc != nil {
- *slc = (*slc)[:n]
- } else if arr := i.arr; arr != nil {
- arr.next = n
- }
-}