Skip to content

Commit

Permalink
feat: GetCb
Browse files Browse the repository at this point in the history
  • Loading branch information
lockp111 committed Aug 15, 2024
1 parent edc1583 commit 1360097
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 17 deletions.
16 changes: 14 additions & 2 deletions cmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@ func (m ConcurrentMap[K, V]) GetOrInsert(key K, cb InsertCb[V]) V {
return v
}

// GetCb is a callback executed in a map.GetCb() call, while Lock is held
// If returns true, the element will be inserted into the map
type GetCb[V any] func(value V, exists bool)

// GetCb locks the shard containing the key, retrieves its current value and calls the callback with those params
func (m ConcurrentMap[K, V]) GetCb(key K, cb GetCb[V]) {
// Get shard
shard := m.GetShard(key)
v, exist := shard.Get(key)
cb(v, exist)
}

// Count returns the number of elements within the map.
func (m ConcurrentMap[K, V]) Count() int {
count := 0
Expand Down Expand Up @@ -171,7 +183,7 @@ func (m ConcurrentMap[K, V]) Remove(key K) {

// RemoveCb is a callback executed in a map.RemoveCb() call, while Lock is held
// If returns true, the element will be removed from the map
type RemoveCb[K any, V any] func(key K, value V, exists bool) bool
type RemoveCb[K any, V any] func(value V, exists bool) bool

// RemoveCb locks the shard containing the key, retrieves its current value and calls the callback with those params
// If callback returns true and element exists, it will remove it from the map
Expand All @@ -181,7 +193,7 @@ func (m ConcurrentMap[K, V]) RemoveCb(key K, cb RemoveCb[K, V]) (ok bool) {
shard := m.GetShard(key)
shard.Update(func(m map[K]V) {
v, exist := m[key]
result := cb(key, v, exist)
result := cb(v, exist)
ok = exist && result
if ok {
delete(m, key)
Expand Down
53 changes: 38 additions & 15 deletions cmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,10 @@ func TestRemoveCb(t *testing.T) {
m.Set("elephant", elephant)

var (
mapKey string
mapVal Animal
wasFound bool
)
cb := func(key string, val Animal, exists bool) bool {
mapKey = key
cb := func(val Animal, exists bool) bool {
mapVal = val
wasFound = exists

Expand All @@ -145,10 +143,6 @@ func TestRemoveCb(t *testing.T) {
t.Errorf("Result was not true")
}

if mapKey != "monkey" {
t.Error("Wrong key was provided to the callback")
}

if mapVal != monkey {
t.Errorf("Wrong value was provided to the value")
}
Expand All @@ -167,10 +161,6 @@ func TestRemoveCb(t *testing.T) {
t.Errorf("Result was true")
}

if mapKey != "elephant" {
t.Error("Wrong key was provided to the callback")
}

if mapVal != elephant {
t.Errorf("Wrong value was provided to the value")
}
Expand All @@ -189,10 +179,6 @@ func TestRemoveCb(t *testing.T) {
t.Errorf("Result was true")
}

if mapKey != "horse" {
t.Error("Wrong key was provided to the callback")
}

if (mapVal != Animal{}) {
t.Errorf("Wrong value was provided to the value")
}
Expand Down Expand Up @@ -672,3 +658,40 @@ func TestGetOrInsert(t *testing.T) {
})
}
}

func TestGetCb(t *testing.T) {
// 初始化一个ConcurrentMap
m := New[string]()

// 定义测试用例
tests := []struct {
name string
key string
value string
wantValue string
}{
{"v1", "key1", "value1", "value1"},
{"v2", "key2", "value2", "value2"},
{"v3", "key3", "value3", "value3"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 在map中设置键值对
m.Set(tt.key, tt.value)

// 定义回调函数
cb := func(v string, exist bool) {
if !exist {
t.Errorf("GetCb(%s) not exist", tt.key)
}
if v != tt.value {
t.Errorf("GetCb() v = %v, wantValue = %v", v, tt.value)
}
}

// 调用待测函数
m.GetCb(tt.key, cb)
})
}
}

0 comments on commit 1360097

Please sign in to comment.