]> 127.0.0.1 Git - part/.git/commitdiff
1 v0.28.20240708182044
authorqydysky <qydysky@foxmail.com>
Mon, 8 Jul 2024 18:14:45 +0000 (18:14 +0000)
committerqydysky <qydysky@foxmail.com>
Mon, 8 Jul 2024 18:14:45 +0000 (18:14 +0000)
sync/Map.go
sync/Map_test.go

index 6eb3de1a9d3fcdd0cfd13966abdeb8a82a59dc59..bcbcd5aae866cd1b72a61e33bc138102e37d695e 100644 (file)
@@ -25,6 +25,46 @@ func (t *Map) LoadOrStore(k, v any) (actual any, loaded bool) {
        return
 }
 
+type LoadOrStoreFunc[T any] struct {
+       Init  func() *T
+       cache *T
+       l     sync.Mutex
+}
+
+func (l *LoadOrStoreFunc[T]) LoadOrStore(t interface {
+       LoadOrStore(k, v any) (actual any, loaded bool)
+}, k any) (actual T, loaded bool) {
+       l.l.Lock()
+       defer l.l.Unlock()
+
+       if l.cache == nil {
+               l.cache = l.Init()
+       }
+       if actual, loaded := t.LoadOrStore(k, l.cache); !loaded {
+               l.cache = nil
+               return *(actual.(*T)), false
+       } else {
+               return *(actual.(*T)), true
+       }
+}
+
+func (l *LoadOrStoreFunc[T]) LoadOrStoreP(t interface {
+       LoadOrStore(k, v any) (actual any, loaded bool)
+}, k any) (actual *T, loaded bool) {
+       l.l.Lock()
+       defer l.l.Unlock()
+
+       if l.cache == nil {
+               l.cache = l.Init()
+       }
+       if actual, loaded := t.LoadOrStore(k, l.cache); !loaded {
+               l.cache = nil
+               return actual.(*T), false
+       } else {
+               return actual.(*T), true
+       }
+}
+
 func (t *Map) Load(k any) (any, bool) {
        return t.m.Load(k)
 }
@@ -66,6 +106,15 @@ func (t *Map) Copy() (m Map) {
        return
 }
 
+func (t *Map) CopyP() (m *Map) {
+       m = &Map{}
+       t.Range(func(k, v any) bool {
+               m.Store(k, v)
+               return true
+       })
+       return
+}
+
 func Copy[T comparable, S any](s map[T]S) map[T]S {
        t := make(map[T]S)
        for k, v := range s {
index 7b097253f37a22eac14d0313b85c7d8fca758890..805e8924c32eacba36a072b15b9271070ca075d9 100644 (file)
@@ -11,6 +11,27 @@ type tmp struct {
        p int
 }
 
+func TestLS(t *testing.T) {
+       var c Map
+       var ls = LoadOrStoreFunc[int]{
+               Init: func() *int {
+                       var i = 1
+                       return &i
+               },
+       }
+       a0, l0 := ls.LoadOrStore(&c, `1`)
+       if l0 {
+               t.Fatal()
+       }
+       a1, l1 := ls.LoadOrStore(&c, `1`)
+       if !l1 {
+               t.Fatal()
+       }
+       if a0 != a1 {
+               t.Fatal()
+       }
+}
+
 func Test_customMap(t *testing.T) {
        var c Map
        //set