yjp 1 жил өмнө
parent
commit
816826d96f

+ 46 - 7
syncutils/sync_slice.go

@@ -55,12 +55,13 @@ func (syncSlice *SyncSlice[T]) AppendNoLock(elements ...T) {
 	syncSlice.appendNoLock(elements...)
 }
 
-func (syncSlice *SyncSlice[T]) DeleteAtNoLock(index int) {
+func (syncSlice *SyncSlice[T]) DeleteAtNoLock(index int) T {
 	if index < 0 {
-		return
+		var zero T
+		return zero
 	}
 
-	syncSlice.deleteAtNoLock(index)
+	return syncSlice.deleteAtNoLock(index)
 }
 
 func (syncSlice *SyncSlice[T]) RangeNoLock(rangeFunc RangeFunc[T]) {
@@ -71,6 +72,14 @@ func (syncSlice *SyncSlice[T]) RangeNoLock(rangeFunc RangeFunc[T]) {
 	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
@@ -82,15 +91,16 @@ func (syncSlice *SyncSlice[T]) Append(elements ...T) {
 	syncSlice.appendNoLock(elements...)
 }
 
-func (syncSlice *SyncSlice[T]) DeleteAt(index int) {
+func (syncSlice *SyncSlice[T]) DeleteAt(index int) T {
 	if index < 0 {
-		return
+		var zero T
+		return zero
 	}
 
 	syncSlice.writeLocker.Lock()
 	defer syncSlice.writeLocker.Unlock()
 
-	syncSlice.deleteAtNoLock(index)
+	return syncSlice.deleteAtNoLock(index)
 }
 
 func (syncSlice *SyncSlice[T]) Range(rangeFunc RangeFunc[T]) {
@@ -104,12 +114,33 @@ func (syncSlice *SyncSlice[T]) Range(rangeFunc RangeFunc[T]) {
 	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) {
+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]) {
@@ -120,3 +151,11 @@ func (syncSlice *SyncSlice[T]) rangeNoLock(rangeFunc RangeFunc[T]) {
 		}
 	}
 }
+
+func (syncSlice *SyncSlice[T]) lenNoLock() int {
+	return len(syncSlice.s)
+}
+
+func (syncSlice *SyncSlice[T]) capNoLock() int {
+	return cap(syncSlice.s)
+}

+ 32 - 4
syncutils/sync_slice_test.go

@@ -10,13 +10,20 @@ func TestSyncSlice(t *testing.T) {
 	syncSlice := NewSyncSlice([]string{"aaa", "bbb", "ccc"}, false)
 
 	syncSlice.Append("ddd")
+	fmt.Println("Len:", syncSlice.Len())
+	fmt.Println("Cap:", syncSlice.Cap())
+	fmt.Println()
+
 	syncSlice.Range(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
 	})
 	fmt.Println()
 
-	syncSlice.DeleteAt(3)
+	deleted := syncSlice.DeleteAt(3)
+	fmt.Println("Deleted:", deleted)
+	fmt.Println()
+
 	syncSlice.Range(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
@@ -26,13 +33,20 @@ func TestSyncSlice(t *testing.T) {
 	syncSlice.Lock()
 
 	syncSlice.AppendNoLock("ddd")
+	fmt.Println("Len:", syncSlice.LenNoLock())
+	fmt.Println("Cap:", syncSlice.CapNoLock())
+	fmt.Println()
+
 	syncSlice.RangeNoLock(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
 	})
 	fmt.Println()
 
-	syncSlice.DeleteAtNoLock(3)
+	deleted = syncSlice.DeleteAtNoLock(3)
+	fmt.Println("Deleted:", deleted)
+	fmt.Println()
+
 	syncSlice.RangeNoLock(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
@@ -44,13 +58,20 @@ func TestSyncSlice(t *testing.T) {
 	rwSyncSlice := NewSyncSlice([]string{"aaa", "bbb", "ccc"}, true)
 
 	rwSyncSlice.Append("ddd")
+	fmt.Println("Len:", rwSyncSlice.Len())
+	fmt.Println("Cap:", rwSyncSlice.Cap())
+	fmt.Println()
+
 	rwSyncSlice.Range(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
 	})
 	fmt.Println()
 
-	rwSyncSlice.DeleteAt(3)
+	deleted = rwSyncSlice.DeleteAt(3)
+	fmt.Println("Deleted:", deleted)
+	fmt.Println()
+
 	rwSyncSlice.Range(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
@@ -60,13 +81,20 @@ func TestSyncSlice(t *testing.T) {
 	rwSyncSlice.Lock()
 
 	rwSyncSlice.AppendNoLock("ddd")
+	fmt.Println("Len:", rwSyncSlice.LenNoLock())
+	fmt.Println("Cap:", rwSyncSlice.CapNoLock())
+	fmt.Println()
+
 	rwSyncSlice.RangeNoLock(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false
 	})
 	fmt.Println()
 
-	rwSyncSlice.DeleteAtNoLock(3)
+	deleted = rwSyncSlice.DeleteAtNoLock(3)
+	fmt.Println("Deleted:", deleted)
+	fmt.Println()
+
 	rwSyncSlice.RangeNoLock(func(index int, e string) bool {
 		fmt.Println("Index", strconv.Itoa(index)+":", e)
 		return false

+ 30 - 0
syncutils/sync_var.go

@@ -0,0 +1,30 @@
+package syncutils
+
+import "sync"
+
+type SyncVar[T any] struct {
+	writeLocker sync.Locker
+	readLocker  sync.Locker
+	v           T
+}
+
+func NewSyncVar[T any](v T, isRWMutex bool) *SyncVar[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 &SyncVar[T]{
+		writeLocker: writeLocker,
+		readLocker:  readLocker,
+		v:           v,
+	}
+}