github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/container/concurrent_array.go (about) 1 package container 2 3 import ( 4 "fmt" 5 "sync/atomic" 6 "unsafe" 7 8 "github.com/nyan233/littlerpc/internal/reflect" 9 ) 10 11 type ConcurrentArray[Value any] struct { 12 slice reflect.SliceHeader 13 } 14 15 func NewConcurrentArray[V any](cap int) *ConcurrentArray[V] { 16 rawSlice := make([]*V, cap, cap) 17 return &ConcurrentArray[V]{ 18 slice: *(*reflect.SliceHeader)(unsafe.Pointer(&rawSlice)), 19 } 20 } 21 22 func (a *ConcurrentArray[Value]) Access(i int) *Value { 23 if i < 0 || i >= a.slice.Cap { 24 panic(fmt.Sprintf("index out of range [%d:%d]", i, a.slice.Cap)) 25 } 26 offset := reflect.PtrSize * uintptr(i) 27 return (*Value)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(uintptr(a.slice.Data) + offset)))) 28 } 29 30 func (a *ConcurrentArray[Value]) Swap(i int, v *Value) (old *Value) { 31 if i < 0 || i >= a.slice.Cap { 32 panic(fmt.Sprintf("index out of range [%d:%d]", i, a.slice.Cap)) 33 } 34 offset := reflect.PtrSize * uintptr(i) 35 return (*Value)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(uintptr(a.slice.Data)+offset)), unsafe.Pointer(v))) 36 } 37 38 func (a *ConcurrentArray[Value]) Cap() int { 39 return a.slice.Cap 40 }