From 4aebc66899cdb93b12c38c150d1e43158f78ee9f Mon Sep 17 00:00:00 2001 From: Potter Dai Date: Thu, 16 Nov 2017 09:59:30 -0500 Subject: [PATCH 1/4] Revise SetIfAbsent to return actual value. --- concurrent_map.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/concurrent_map.go b/concurrent_map.go index 0e2319c..e17911f 100644 --- a/concurrent_map.go +++ b/concurrent_map.go @@ -67,16 +67,17 @@ func (m ConcurrentMap) Upsert(key string, value interface{}, cb UpsertCb) (res i } // Sets the given value under the specified key if no value was associated with it. -func (m ConcurrentMap) SetIfAbsent(key string, value interface{}) bool { +func (m ConcurrentMap) SetIfAbsent(key string, value interface{}) (actual interface{}, set bool) { // Get map shard. shard := m.GetShard(key) shard.Lock() - _, ok := shard.items[key] + actual, ok := shard.items[key] if !ok { shard.items[key] = value + actual = value } shard.Unlock() - return !ok + return actual, !ok } // Retrieves an element from map under given key. From d5da08f302988dc8f75d23ae8ca04418692d52c1 Mon Sep 17 00:00:00 2001 From: Potter Dai Date: Thu, 16 Nov 2017 10:03:29 -0500 Subject: [PATCH 2/4] Fix test code. --- concurrent_map_test.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/concurrent_map_test.go b/concurrent_map_test.go index 5861f12..99e3c08 100644 --- a/concurrent_map_test.go +++ b/concurrent_map_test.go @@ -42,7 +42,7 @@ func TestInsertAbsent(t *testing.T) { monkey := Animal{"monkey"} m.SetIfAbsent("elephant", elephant) - if ok := m.SetIfAbsent("elephant", monkey); ok { + if _, ok := m.SetIfAbsent("elephant", monkey); ok { t.Error("map set a new value even the entry is already present") } } @@ -133,10 +133,9 @@ func TestRemoveCb(t *testing.T) { m.Set("elephant", elephant) var ( - mapKey string - mapVal interface{} + mapKey string + mapVal interface{} wasFound bool - ) cb := func(key string, val interface{}, exists bool) bool { mapKey = key From 0d2a64b22f18d41e02c5e7a7ffc91a448de38420 Mon Sep 17 00:00:00 2001 From: Potter Dai Date: Thu, 16 Nov 2017 10:04:44 -0500 Subject: [PATCH 3/4] . --- concurrent_map.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concurrent_map.go b/concurrent_map.go index e17911f..22695d7 100644 --- a/concurrent_map.go +++ b/concurrent_map.go @@ -67,7 +67,7 @@ func (m ConcurrentMap) Upsert(key string, value interface{}, cb UpsertCb) (res i } // Sets the given value under the specified key if no value was associated with it. -func (m ConcurrentMap) SetIfAbsent(key string, value interface{}) (actual interface{}, set bool) { +func (m ConcurrentMap) SetIfAbsent(key string, value interface{}) (actual interface{}, absent bool) { // Get map shard. shard := m.GetShard(key) shard.Lock() From fc34a3fe2d5440e5a3d92fabc07ed65c99d94053 Mon Sep 17 00:00:00 2001 From: Potter Dai Date: Thu, 16 Nov 2017 11:33:39 -0500 Subject: [PATCH 4/4] . --- concurrent_map.go | 15 ++++++++++++++- concurrent_map_test.go | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/concurrent_map.go b/concurrent_map.go index 22695d7..0baa06c 100644 --- a/concurrent_map.go +++ b/concurrent_map.go @@ -67,7 +67,20 @@ func (m ConcurrentMap) Upsert(key string, value interface{}, cb UpsertCb) (res i } // Sets the given value under the specified key if no value was associated with it. -func (m ConcurrentMap) SetIfAbsent(key string, value interface{}) (actual interface{}, absent bool) { +func (m ConcurrentMap) SetIfAbsent(key string, value interface{}) bool { + // Get map shard. + shard := m.GetShard(key) + shard.Lock() + _, ok := shard.items[key] + if !ok { + shard.items[key] = value + } + shard.Unlock() + return !ok +} + +// Sets the given value under the specified key if no value was associated with it, otherwise return existing value +func (m ConcurrentMap) SetOrGet(key string, value interface{}) (actual interface{}, absent bool) { // Get map shard. shard := m.GetShard(key) shard.Lock() diff --git a/concurrent_map_test.go b/concurrent_map_test.go index 99e3c08..c3d5f05 100644 --- a/concurrent_map_test.go +++ b/concurrent_map_test.go @@ -42,7 +42,7 @@ func TestInsertAbsent(t *testing.T) { monkey := Animal{"monkey"} m.SetIfAbsent("elephant", elephant) - if _, ok := m.SetIfAbsent("elephant", monkey); ok { + if ok := m.SetIfAbsent("elephant", monkey); ok { t.Error("map set a new value even the entry is already present") } }