From 1e47f4eda8772536b63ef866209e65b6b81cae37 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 7 Aug 2025 14:01:12 -0300 Subject: [PATCH] feat(csync.Map): added GetOrSet Signed-off-by: Carlos Alexandro Becker --- internal/csync/maps.go | 12 ++++++++++++ internal/csync/maps_test.go | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/internal/csync/maps.go b/internal/csync/maps.go index 67796baff9f68b2a02382de625de70b78e204f4a..b7a1f3109f6c15e7e5592cb538943a2d9e340819 100644 --- a/internal/csync/maps.go +++ b/internal/csync/maps.go @@ -56,6 +56,18 @@ func (m *Map[K, V]) Len() int { return len(m.inner) } +// GetOrSet gets and returns the key if it exists, otherwise, it executes the +// given function, set its return value for the given key, and returns it. +func (m *Map[K, V]) GetOrSet(key K, fn func() V) V { + got, ok := m.Get(key) + if ok { + return got + } + value := fn() + m.Set(key, value) + return value +} + // Take gets an item and then deletes it. func (m *Map[K, V]) Take(key K) (V, bool) { m.mu.Lock() diff --git a/internal/csync/maps_test.go b/internal/csync/maps_test.go index 2b1f1387f14a5feae3ad86d77482baaf4494c718..4a8019260a2610b7f5ae0d854029207c6b945d04 100644 --- a/internal/csync/maps_test.go +++ b/internal/csync/maps_test.go @@ -54,6 +54,16 @@ func TestMap_Set(t *testing.T) { require.Equal(t, 1, m.Len()) } +func TestMap_GetOrSet(t *testing.T) { + t.Parallel() + + m := NewMap[string, int]() + + require.Equal(t, 42, m.GetOrSet("key1", func() int { return 42 })) + require.Equal(t, 42, m.GetOrSet("key1", func() int { return 99999 })) + require.Equal(t, 1, m.Len()) +} + func TestMap_Get(t *testing.T) { t.Parallel()