|
@@ -0,0 +1,122 @@
|
|
|
+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) {
|
|
|
+ if index < 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ syncSlice.deleteAtNoLock(index)
|
|
|
+}
|
|
|
+
|
|
|
+func (syncSlice *SyncSlice[T]) RangeNoLock(rangeFunc RangeFunc[T]) {
|
|
|
+ if rangeFunc == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ syncSlice.rangeNoLock(rangeFunc)
|
|
|
+}
|
|
|
+
|
|
|
+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) {
|
|
|
+ if index < 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ syncSlice.writeLocker.Lock()
|
|
|
+ defer syncSlice.writeLocker.Unlock()
|
|
|
+
|
|
|
+ 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]) appendNoLock(elements ...T) {
|
|
|
+ syncSlice.s = append(syncSlice.s, elements...)
|
|
|
+}
|
|
|
+
|
|
|
+func (syncSlice *SyncSlice[T]) deleteAtNoLock(index int) {
|
|
|
+ syncSlice.s = append(syncSlice.s[:index], syncSlice.s[index+1:]...)
|
|
|
+}
|
|
|
+
|
|
|
+func (syncSlice *SyncSlice[T]) rangeNoLock(rangeFunc RangeFunc[T]) {
|
|
|
+ for i, e := range syncSlice.s {
|
|
|
+ stop := rangeFunc(i, e)
|
|
|
+ if stop {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|