From: qydysky Date: Mon, 8 Jul 2024 18:14:45 +0000 (+0000) Subject: 1 X-Git-Tag: v0.28.20240708182044 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=269c06a5850f1b4cd7baea8b6580c0879a751347;p=part%2F.git 1 --- diff --git a/sync/Map.go b/sync/Map.go index 6eb3de1..bcbcd5a 100644 --- a/sync/Map.go +++ b/sync/Map.go @@ -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 { diff --git a/sync/Map_test.go b/sync/Map_test.go index 7b09725..805e892 100644 --- a/sync/Map_test.go +++ b/sync/Map_test.go @@ -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