package syncutils import "sync" type RangeFunc[T any] func(index int, e T) bool type SyncSlice[T any] struct { writeLocker sync.Locker readLocker sync.Locker s []T } func NewSyncSlice[T any](s []T, isRWMutex bool) *SyncSlice[T] { var writeLocker sync.Locker var readLocker sync.Locker if !isRWMutex { mutex := &sync.Mutex{} writeLocker = mutex readLocker = mutex } else { mutex := &sync.RWMutex{} writeLocker = mutex readLocker = mutex.RLocker() } return &SyncSlice[T]{ writeLocker: writeLocker, readLocker: readLocker, s: s, } } func (syncSlice *SyncSlice[T]) Lock() { syncSlice.writeLocker.Lock() } func (syncSlice *SyncSlice[T]) Unlock() { syncSlice.writeLocker.Unlock() } func (syncSlice *SyncSlice[T]) RLock() { syncSlice.readLocker.Lock() } func (syncSlice *SyncSlice[T]) RUnlock() { syncSlice.readLocker.Unlock() } func (syncSlice *SyncSlice[T]) AppendNoLock(elements ...T) { if elements == nil || len(elements) == 0 { return } syncSlice.appendNoLock(elements...) } func (syncSlice *SyncSlice[T]) DeleteAtNoLock(index int) T { if index < 0 { var zero T return zero } return syncSlice.deleteAtNoLock(index) } func (syncSlice *SyncSlice[T]) RangeNoLock(rangeFunc RangeFunc[T]) { if rangeFunc == nil { return } syncSlice.rangeNoLock(rangeFunc) } func (syncSlice *SyncSlice[T]) LenNoLock() int { return syncSlice.lenNoLock() } func (syncSlice *SyncSlice[T]) CapNoLock() int { return syncSlice.capNoLock() } func (syncSlice *SyncSlice[T]) Append(elements ...T) { if elements == nil || len(elements) == 0 { return } syncSlice.writeLocker.Lock() defer syncSlice.writeLocker.Unlock() syncSlice.appendNoLock(elements...) } func (syncSlice *SyncSlice[T]) DeleteAt(index int) T { if index < 0 { var zero T return zero } syncSlice.writeLocker.Lock() defer syncSlice.writeLocker.Unlock() return syncSlice.deleteAtNoLock(index) } func (syncSlice *SyncSlice[T]) Range(rangeFunc RangeFunc[T]) { if rangeFunc == nil { return } syncSlice.readLocker.Lock() defer syncSlice.readLocker.Unlock() syncSlice.rangeNoLock(rangeFunc) } func (syncSlice *SyncSlice[T]) Len() int { syncSlice.readLocker.Lock() defer syncSlice.readLocker.Unlock() return syncSlice.lenNoLock() } func (syncSlice *SyncSlice[T]) Cap() int { syncSlice.readLocker.Lock() defer syncSlice.readLocker.Unlock() return syncSlice.capNoLock() } func (syncSlice *SyncSlice[T]) appendNoLock(elements ...T) { syncSlice.s = append(syncSlice.s, elements...) } func (syncSlice *SyncSlice[T]) deleteAtNoLock(index int) T { if len(syncSlice.s)-1 < index { var zero T return zero } v := syncSlice.s[index] syncSlice.s = append(syncSlice.s[:index], syncSlice.s[index+1:]...) return v } func (syncSlice *SyncSlice[T]) rangeNoLock(rangeFunc RangeFunc[T]) { for i, e := range syncSlice.s { stop := rangeFunc(i, e) if stop { return } } } func (syncSlice *SyncSlice[T]) lenNoLock() int { return len(syncSlice.s) } func (syncSlice *SyncSlice[T]) capNoLock() int { return cap(syncSlice.s) }