// 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) } }