92 lines
1.7 KiB
Go
92 lines
1.7 KiB
Go
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|
|
|
package syncutils
|
|
|
|
import (
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/procs"
|
|
"runtime"
|
|
"sync"
|
|
)
|
|
|
|
type Values[T any] struct {
|
|
count int
|
|
values []T
|
|
muList []*sync.RWMutex
|
|
}
|
|
|
|
func NewValues[T any](newFn func() T) *Values[T] {
|
|
var countProcs = runtime.GOMAXPROCS(0)
|
|
if countProcs < 0 {
|
|
countProcs = 32
|
|
}
|
|
|
|
var values []T
|
|
for i := 0; i < countProcs; i++ {
|
|
values = append(values, newFn())
|
|
}
|
|
|
|
var muList []*sync.RWMutex
|
|
for i := 0; i < countProcs; i++ {
|
|
muList = append(muList, &sync.RWMutex{})
|
|
}
|
|
|
|
return &Values[T]{
|
|
count: countProcs,
|
|
values: values,
|
|
muList: muList,
|
|
}
|
|
}
|
|
|
|
func (this *Values[T]) Len() int {
|
|
return this.count
|
|
}
|
|
|
|
func (this *Values[T]) DoReadAll(f func(value T)) {
|
|
for i := 0; i < this.count; i++ {
|
|
var mu = this.muList[i]
|
|
var value = this.values[i]
|
|
mu.RLock()
|
|
f(value)
|
|
mu.RUnlock()
|
|
}
|
|
}
|
|
|
|
func (this *Values[T]) DoRead(f func(value T)) {
|
|
var procId = procs.Id()
|
|
var mu = this.muList[procId]
|
|
var value = this.values[procId]
|
|
mu.RLock()
|
|
f(value)
|
|
mu.RUnlock()
|
|
}
|
|
|
|
func (this *Values[T]) DoWriteAll(f func(value T)) {
|
|
for i := 0; i < this.count; i++ {
|
|
var mu = this.muList[i]
|
|
var value = this.values[i]
|
|
mu.Lock()
|
|
f(value)
|
|
mu.Unlock()
|
|
}
|
|
}
|
|
|
|
func (this *Values[T]) DoWrite(f func(value T)) {
|
|
var procId = procs.Id()
|
|
var mu = this.muList[procId]
|
|
var value = this.values[procId]
|
|
mu.Lock()
|
|
f(value)
|
|
mu.Unlock()
|
|
}
|
|
|
|
func (this *Values[T]) DoUnsafe(f func(value *T)) {
|
|
var procId = procs.Id()
|
|
f(&this.values[procId])
|
|
}
|
|
|
|
func (this *Values[T]) DoUnsafeAll(f func(value T)) {
|
|
for _, value := range this.values {
|
|
f(value)
|
|
}
|
|
}
|