From ace6ba8096b407f3c811e729b997ae2d069f6236 Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Mon, 8 Apr 2019 17:02:57 +0800 Subject: [PATCH 1/7] =?UTF-8?q?Gmap=20=E6=B5=8B=E8=AF=95=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gmap_z_interface_interface_basic_test.go | 50 +++++++++++++ .../gmap/gmap_z_normal_example_test.go | 71 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 g/container/gmap/gmap_z_interface_interface_basic_test.go create mode 100644 g/container/gmap/gmap_z_normal_example_test.go diff --git a/g/container/gmap/gmap_z_interface_interface_basic_test.go b/g/container/gmap/gmap_z_interface_interface_basic_test.go new file mode 100644 index 000000000..bf10d70f6 --- /dev/null +++ b/g/container/gmap/gmap_z_interface_interface_basic_test.go @@ -0,0 +1,50 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) +func getValue()interface{}{ + return 3 +} + +func Test_Map_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.New() + m.Set("key1", "val1") + gtest.Assert(m.Get("key1"), "val1") + m.BatchSet(map[interface{}]interface{}{1: 1, "key2": "val2", "key3": "val3"}) + gtest.Assert(m.Size(), 4) + gtest.Assert(m.IsEmpty(), false) + gtest.Assert(m.GetOrSet("key4", "val4"), "val4") + gtest.Assert(m.SetIfNotExist("key4", "val4"), false) + gtest.Assert(m.Remove("key2"), "val2") + m.BatchRemove([]interface{}{"key1", 1}) + gtest.Assert(m.Contains("key3"), true) + m.Flip() + gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val4": "key4"}) + m.GetOrSetFunc("fun",getValue) + gtest.Assert(m.Get("fun"),3) + m.GetOrSetFunc("fun",getValue) + gtest.Assert(m.SetIfNotExistFunc("fun",getValue),false) + + m.Clear() + gtest.Assert(m.Size(), 0) + m2 := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) + gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) + m3 := gmap.NewFromArray([]interface{}{1, "key1"}, []interface{}{1, "val1"}) + gtest.Assert(m3.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) + m4 := m3.Clone() + gtest.Assert(m4.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) + + }) +} +func Test_Map_Basic_Merge(t *testing.T) { + m1 := gmap.New() + m2 := gmap.New() + m1.Set("key1", "val1") + m2.Set("key2", "val2") + m1.Merge(m2) + gtest.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"}) +} diff --git a/g/container/gmap/gmap_z_normal_example_test.go b/g/container/gmap/gmap_z_normal_example_test.go new file mode 100644 index 000000000..b134c5ff8 --- /dev/null +++ b/g/container/gmap/gmap_z_normal_example_test.go @@ -0,0 +1,71 @@ +package gmap_test + +import ( + "fmt" + "github.com/gogf/gf/g/container/gmap" +) + +func Example_Normal_Basic() { + m := gmap.New() + + //Add data + m.Set("key1", "val1") + + //Print size + fmt.Println(m.Size()) + //output 1 + + add_map := make(map[interface{}]interface{}) + add_map["key2"] = "val2" + add_map["key3"] = "val3" + add_map[1] = 1 + + fmt.Println(m.Values()) + + //Batch add data + m.BatchSet(add_map) + + //Gets the value of the corresponding key + key3_val := m.Get("key3") + fmt.Println(key3_val) + + //Get the value by key, or set it with given key-value if not exist. + get_or_set_val := m.GetOrSet("key4", "val4") + fmt.Println(get_or_set_val) + + // Set key-value if the key does not exist, then return true; or else return false. + is_set := m.SetIfNotExist("key3", "val3") + fmt.Println(is_set) + + //Remove key + m.Remove("key2") + fmt.Println(m.Keys()) + + //Batch remove keys + remove_keys := []interface{}{"key1", 1} + m.BatchRemove(remove_keys) + fmt.Println(m.Keys()) + + //Contains checks whether a key exists. + is_contain := m.Contains("key3") + fmt.Println(is_contain) + + //Flip exchanges key-value of the map, it will change key-value to value-key. + m.Flip() + fmt.Println(m.Map()) + + // Clear deletes all data of the map, + m.Clear() + + fmt.Println(m.Size()) + +} +func Example_Normal_Merge(){ + m1 := gmap.New() + m2 := gmap.New() + m1.Set("key1","val1") + m2.Set("key2","val2") + m1.Merge(m2) + fmt.Println(m1.Map()) +} + From b97bbbfa3d216db06d70f4a2620f10d9e8d2e94e Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Mon, 8 Apr 2019 17:32:07 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/gmap_z_interface_interface_basic_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/g/container/gmap/gmap_z_interface_interface_basic_test.go b/g/container/gmap/gmap_z_interface_interface_basic_test.go index bf10d70f6..079c20015 100644 --- a/g/container/gmap/gmap_z_interface_interface_basic_test.go +++ b/g/container/gmap/gmap_z_interface_interface_basic_test.go @@ -13,6 +13,9 @@ func Test_Map_Basic(t *testing.T) { gtest.Case(t, func() { m := gmap.New() m.Set("key1", "val1") + gtest.Assert(m.Keys(),[]interface{}{"key1"}) + gtest.Assert(m.Values(),[]interface{}{"val1"}) + gtest.Assert(m.Get("key1"), "val1") m.BatchSet(map[interface{}]interface{}{1: 1, "key2": "val2", "key3": "val3"}) gtest.Assert(m.Size(), 4) @@ -25,10 +28,11 @@ func Test_Map_Basic(t *testing.T) { m.Flip() gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val4": "key4"}) m.GetOrSetFunc("fun",getValue) + m.GetOrSetFuncLock("funlock",getValue) + gtest.Assert(m.Get("funlock"),3) gtest.Assert(m.Get("fun"),3) m.GetOrSetFunc("fun",getValue) gtest.Assert(m.SetIfNotExistFunc("fun",getValue),false) - m.Clear() gtest.Assert(m.Size(), 0) m2 := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) From 39c65d9e9a0beadb045151a693466f7959875d58 Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Mon, 8 Apr 2019 17:49:15 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/gmap_z_interface_interface_basic_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/g/container/gmap/gmap_z_interface_interface_basic_test.go b/g/container/gmap/gmap_z_interface_interface_basic_test.go index 079c20015..b5de111d2 100644 --- a/g/container/gmap/gmap_z_interface_interface_basic_test.go +++ b/g/container/gmap/gmap_z_interface_interface_basic_test.go @@ -33,6 +33,8 @@ func Test_Map_Basic(t *testing.T) { gtest.Assert(m.Get("fun"),3) m.GetOrSetFunc("fun",getValue) gtest.Assert(m.SetIfNotExistFunc("fun",getValue),false) + gtest.Assert(m.SetIfNotExistFuncLock("funlock",getValue),false) + m.Clear() gtest.Assert(m.Size(), 0) m2 := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) From 277b7a453641f3f84fe829490248d721272a0a9a Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Tue, 9 Apr 2019 15:06:12 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gmap_z_interface_interface_basic_test.go | 76 ++++++++++++++----- 1 file changed, 56 insertions(+), 20 deletions(-) diff --git a/g/container/gmap/gmap_z_interface_interface_basic_test.go b/g/container/gmap/gmap_z_interface_interface_basic_test.go index b5de111d2..6f23e4155 100644 --- a/g/container/gmap/gmap_z_interface_interface_basic_test.go +++ b/g/container/gmap/gmap_z_interface_interface_basic_test.go @@ -5,47 +5,83 @@ import ( "github.com/gogf/gf/g/test/gtest" "testing" ) -func getValue()interface{}{ + +func getValue() interface{} { return 3 } - +func callBack(k interface{}, v interface{}) bool { + return true +} func Test_Map_Basic(t *testing.T) { gtest.Case(t, func() { m := gmap.New() m.Set("key1", "val1") - gtest.Assert(m.Keys(),[]interface{}{"key1"}) - gtest.Assert(m.Values(),[]interface{}{"val1"}) + gtest.Assert(m.Keys(), []interface{}{"key1"}) + gtest.Assert(m.Values(), []interface{}{"val1"}) gtest.Assert(m.Get("key1"), "val1") - m.BatchSet(map[interface{}]interface{}{1: 1, "key2": "val2", "key3": "val3"}) - gtest.Assert(m.Size(), 4) + gtest.Assert(m.Size(), 1) gtest.Assert(m.IsEmpty(), false) - gtest.Assert(m.GetOrSet("key4", "val4"), "val4") - gtest.Assert(m.SetIfNotExist("key4", "val4"), false) + + gtest.Assert(m.GetOrSet("key2", "val2"), "val2") + gtest.Assert(m.SetIfNotExist("key2", "val2"), false) + + gtest.Assert(m.SetIfNotExist("key3", "val3"), true) + gtest.Assert(m.Remove("key2"), "val2") - m.BatchRemove([]interface{}{"key1", 1}) - gtest.Assert(m.Contains("key3"), true) + gtest.Assert(m.Contains("key2"), false) + + gtest.AssertIN("key3", m.Keys()) + gtest.AssertIN("key1", m.Keys()) + gtest.AssertIN("val3", m.Values()) + gtest.AssertIN("val1", m.Values()) + m.Flip() - gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val4": "key4"}) - m.GetOrSetFunc("fun",getValue) - m.GetOrSetFuncLock("funlock",getValue) - gtest.Assert(m.Get("funlock"),3) - gtest.Assert(m.Get("fun"),3) - m.GetOrSetFunc("fun",getValue) - gtest.Assert(m.SetIfNotExistFunc("fun",getValue),false) - gtest.Assert(m.SetIfNotExistFuncLock("funlock",getValue),false) + gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"}) m.Clear() gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + m2 := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) m3 := gmap.NewFromArray([]interface{}{1, "key1"}, []interface{}{1, "val1"}) gtest.Assert(m3.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) - m4 := m3.Clone() - gtest.Assert(m4.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) }) } +func Test_Map_Set_Fun(t *testing.T) { + m := gmap.New() + m.GetOrSetFunc("fun", getValue) + m.GetOrSetFuncLock("funlock", getValue) + gtest.Assert(m.Get("funlock"), 3) + gtest.Assert(m.Get("fun"), 3) + m.GetOrSetFunc("fun", getValue) + gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false) + gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false) +} + +func Test_Map_Batch(t *testing.T) { + m := gmap.New() + m.BatchSet(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}) + m.Iterator(callBack) + gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}) + m.BatchRemove([]interface{}{"key1", 1}) + gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"}) +} + +func Test_Map_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) + m_clone := m.Clone() + m.Remove(1) + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN(1, m_clone.Keys()) + + m_clone.Remove("key1") + //修改clone map,原 map 不影响 + gtest.AssertIN("key1", m.Keys()) +} func Test_Map_Basic_Merge(t *testing.T) { m1 := gmap.New() m2 := gmap.New() From 3a1524ae6d4ed72132f8481c651c7615349ec690 Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Thu, 11 Apr 2019 17:33:52 +0800 Subject: [PATCH 5/7] =?UTF-8?q?Gmap=20=E5=88=9D=E6=B5=8B=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/gmap_z_int_bool_test.go | 87 +++++++++++++++++ g/container/gmap/gmap_z_int_int_test.go | 91 +++++++++++++++++ g/container/gmap/gmap_z_int_interface_test.go | 91 +++++++++++++++++ g/container/gmap/gmap_z_int_string_test.go | 97 +++++++++++++++++++ .../gmap_z_interface_interface_basic_test.go | 1 - g/container/gmap/gmap_z_string_bool_test.go | 85 ++++++++++++++++ g/container/gmap/gmap_z_string_int_test.go | 93 ++++++++++++++++++ .../gmap/gmap_z_string_interface_test.go | 90 +++++++++++++++++ 8 files changed, 634 insertions(+), 1 deletion(-) create mode 100644 g/container/gmap/gmap_z_int_bool_test.go create mode 100644 g/container/gmap/gmap_z_int_int_test.go create mode 100644 g/container/gmap/gmap_z_int_interface_test.go create mode 100644 g/container/gmap/gmap_z_int_string_test.go create mode 100644 g/container/gmap/gmap_z_string_bool_test.go create mode 100644 g/container/gmap/gmap_z_string_int_test.go create mode 100644 g/container/gmap/gmap_z_string_interface_test.go diff --git a/g/container/gmap/gmap_z_int_bool_test.go b/g/container/gmap/gmap_z_int_bool_test.go new file mode 100644 index 000000000..078bd3077 --- /dev/null +++ b/g/container/gmap/gmap_z_int_bool_test.go @@ -0,0 +1,87 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func getBool() bool { + return true +} +func intBoolCallBack(int, bool) bool { + return true +} +func Test_IntBoolMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewIntBoolMap() + m.Set(1, true) + + gtest.Assert(m.Get(1), true) + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet(2, false), false) + gtest.Assert(m.SetIfNotExist(2, false), false) + + gtest.Assert(m.SetIfNotExist(3, false), true) + + gtest.Assert(m.Remove(2), false) + gtest.Assert(m.Contains(2), false) + + gtest.AssertIN(3, m.Keys()) + gtest.AssertIN(1, m.Keys()) + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewIntBoolMapFrom(map[int]bool{1: true, 2: false}) + gtest.Assert(m2.Map(), map[int]bool{1: true, 2: false}) + m3 := gmap.NewIntBoolMapFromArray([]int{1, 2}, []bool{true, false}) + gtest.Assert(m3.Map(), map[int]bool{1: true, 2: false}) + + }) +} +func Test_IntBoolMap_Set_Fun(t *testing.T) { + m := gmap.NewIntBoolMap() + + m.GetOrSetFunc(1, getBool) + m.GetOrSetFuncLock(2, getBool) + gtest.Assert(m.Get(1), true) + gtest.Assert(m.Get(2), true) + gtest.Assert(m.SetIfNotExistFunc(1, getBool), false) + gtest.Assert(m.SetIfNotExistFuncLock(2, getBool), false) +} + +func Test_IntBoolMap_Batch(t *testing.T) { + m := gmap.NewIntBoolMap() + + m.BatchSet(map[int]bool{1: true, 2: false, 3: true}) + m.Iterator(intBoolCallBack) + gtest.Assert(m.Map(), map[int]bool{1: true, 2: false, 3: true}) + m.BatchRemove([]int{1, 2}) + gtest.Assert(m.Map(), map[int]bool{3: true}) +} + +func Test_IntBoolMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewIntBoolMapFrom(map[int]bool{1: true, 2: false}) + + m_clone := m.Clone() + m.Remove(1) + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN(1, m_clone.Keys()) + + m_clone.Remove(2) + //修改clone map,原 map 不影响 + gtest.AssertIN(2, m.Keys()) +} +func Test_IntBoolMap_Merge(t *testing.T) { + m1 := gmap.NewIntBoolMap() + m2 := gmap.NewIntBoolMap() + m1.Set(1, true) + m2.Set(2, false) + m1.Merge(m2) + gtest.Assert(m1.Map(), map[int]bool{1: true, 2: false}) +} diff --git a/g/container/gmap/gmap_z_int_int_test.go b/g/container/gmap/gmap_z_int_int_test.go new file mode 100644 index 000000000..c7151960e --- /dev/null +++ b/g/container/gmap/gmap_z_int_int_test.go @@ -0,0 +1,91 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func getInt() int { + return 123 +} +func intIntCallBack(int, int) bool { + return true +} +func Test_IntIntMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewIntIntMap() + m.Set(1, 1) + + gtest.Assert(m.Get(1), 1) + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet(2, 2), 2) + gtest.Assert(m.SetIfNotExist(2, 2), false) + + gtest.Assert(m.SetIfNotExist(3, 3), true) + + gtest.Assert(m.Remove(2), 2) + gtest.Assert(m.Contains(2), false) + + gtest.AssertIN(3, m.Keys()) + gtest.AssertIN(1, m.Keys()) + gtest.AssertIN(3, m.Values()) + gtest.AssertIN(1, m.Values()) + m.Flip() + gtest.Assert(m.Map(), map[int]int{1: 1, 3: 3}) + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewIntIntMapFrom(map[int]int{1: 1, 2: 2}) + gtest.Assert(m2.Map(), map[int]int{1: 1, 2: 2}) + m3 := gmap.NewIntIntMapFromArray([]int{1, 2}, []int{1, 2}) + gtest.Assert(m3.Map(), map[int]int{1: 1, 2: 2}) + + }) +} +func Test_IntIntMap_Set_Fun(t *testing.T) { + m := gmap.NewIntIntMap() + + m.GetOrSetFunc(1, getInt) + m.GetOrSetFuncLock(2, getInt) + gtest.Assert(m.Get(1), 123) + gtest.Assert(m.Get(2), 123) + gtest.Assert(m.SetIfNotExistFunc(1, getInt), false) + gtest.Assert(m.SetIfNotExistFuncLock(2, getInt), false) +} + +func Test_IntIntMap_Batch(t *testing.T) { + m := gmap.NewIntIntMap() + + m.BatchSet(map[int]int{1: 1, 2: 2, 3: 3}) + m.Iterator(intIntCallBack) + gtest.Assert(m.Map(), map[int]int{1: 1, 2: 2, 3: 3}) + m.BatchRemove([]int{1, 2}) + gtest.Assert(m.Map(), map[int]int{3: 3}) +} + +func Test_IntIntMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewIntIntMapFrom(map[int]int{1: 1, 2: 2}) + + m_clone := m.Clone() + m.Remove(1) + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN(1, m_clone.Keys()) + + m_clone.Remove(2) + //修改clone map,原 map 不影响 + gtest.AssertIN(2, m.Keys()) +} +func Test_IntIntMap_Merge(t *testing.T) { + m1 := gmap.NewIntIntMap() + m2 := gmap.NewIntIntMap() + m1.Set(1, 1) + m2.Set(2, 2) + m1.Merge(m2) + gtest.Assert(m1.Map(), map[int]int{1: 1, 2: 2}) +} diff --git a/g/container/gmap/gmap_z_int_interface_test.go b/g/container/gmap/gmap_z_int_interface_test.go new file mode 100644 index 000000000..eb5a47598 --- /dev/null +++ b/g/container/gmap/gmap_z_int_interface_test.go @@ -0,0 +1,91 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func getInterface() interface{} { + return 123 +} +func intInterfaceCallBack(int, interface{}) bool { + return true +} +func Test_IntInterfaceMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewIntInterfaceMap() + m.Set(1, 1) + + gtest.Assert(m.Get(1), 1) + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet(2, "2"), "2") + gtest.Assert(m.SetIfNotExist(2, "2"), false) + + gtest.Assert(m.SetIfNotExist(3, 3), true) + + gtest.Assert(m.Remove(2), "2") + gtest.Assert(m.Contains(2), false) + + gtest.AssertIN(3, m.Keys()) + gtest.AssertIN(1, m.Keys()) + gtest.AssertIN(3, m.Values()) + gtest.AssertIN(1, m.Values()) + m.Flip() + gtest.Assert(m.Map(), map[interface{}]int{1: 1, 3: 3}) + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewIntInterfaceMapFrom(map[int]interface{}{1: 1, 2: "2"}) + gtest.Assert(m2.Map(), map[int]interface{}{1: 1, 2: "2"}) + m3 := gmap.NewIntInterfaceMapFromArray([]int{1, 2}, []interface{}{1, "2"}) + gtest.Assert(m3.Map(), map[int]interface{}{1: 1, 2: "2"}) + + }) +} +func Test_IntInterfaceMap_Set_Fun(t *testing.T) { + m := gmap.NewIntInterfaceMap() + + m.GetOrSetFunc(1, getInterface) + m.GetOrSetFuncLock(2, getInterface) + gtest.Assert(m.Get(1), 123) + gtest.Assert(m.Get(2), 123) + gtest.Assert(m.SetIfNotExistFunc(1, getInterface), false) + gtest.Assert(m.SetIfNotExistFuncLock(2, getInterface), false) +} + +func Test_IntInterfaceMap_Batch(t *testing.T) { + m := gmap.NewIntInterfaceMap() + + m.BatchSet(map[int]interface{}{1: 1, 2: "2", 3: 3}) + m.Iterator(intInterfaceCallBack) + gtest.Assert(m.Map(), map[int]interface{}{1: 1, 2: "2", 3: 3}) + m.BatchRemove([]int{1, 2}) + gtest.Assert(m.Map(), map[int]interface{}{3: 3}) +} + +func Test_IntInterfaceMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewIntInterfaceMapFrom(map[int]interface{}{1: 1, 2: "2"}) + + m_clone := m.Clone() + m.Remove(1) + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN(1, m_clone.Keys()) + + m_clone.Remove(2) + //修改clone map,原 map 不影响 + gtest.AssertIN(2, m.Keys()) +} +func Test_IntInterfaceMap_Merge(t *testing.T) { + m1 := gmap.NewIntInterfaceMap() + m2 := gmap.NewIntInterfaceMap() + m1.Set(1, 1) + m2.Set(2, "2") + m1.Merge(m2) + gtest.Assert(m1.Map(), map[int]interface{}{1: 1, 2: "2"}) +} diff --git a/g/container/gmap/gmap_z_int_string_test.go b/g/container/gmap/gmap_z_int_string_test.go new file mode 100644 index 000000000..8c1ddb3f5 --- /dev/null +++ b/g/container/gmap/gmap_z_int_string_test.go @@ -0,0 +1,97 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func getString() string { + return "z" +} +func intStringCallBack(int, string) bool { + return true +} +func Test_IntStringMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewIntStringMap() + m.Set(1, "a") + + gtest.Assert(m.Get(1), "a") + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet(2, "b"), "b") + gtest.Assert(m.SetIfNotExist(2, "b"), false) + + gtest.Assert(m.SetIfNotExist(3, "c"), true) + + gtest.Assert(m.Remove(2), "b") + gtest.Assert(m.Contains(2), false) + + gtest.AssertIN(3, m.Keys()) + gtest.AssertIN(1, m.Keys()) + gtest.AssertIN("a", m.Values()) + gtest.AssertIN("c", m.Values()) + + //反转之后不成为以下 map,flip 操作只是翻转原 map + //gtest.Assert(m.Map(), map[string]int{"a": 1, "c": 3}) + m_f := gmap.NewIntStringMap() + m_f.Set(1,"2") + m_f.Flip() + gtest.Assert(m_f.Map(),map[int]string{2:"1"}) + + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewIntStringMapFrom(map[int]string{1: "a", 2: "b"}) + gtest.Assert(m2.Map(), map[int]string{1: "a", 2: "b"}) + m3 := gmap.NewIntStringMapFromArray([]int{1, 2}, []string{"a","b"}) + gtest.Assert(m3.Map(), map[int]string{1: "a", 2: "b"}) + + }) +} +func Test_IntStringMap_Set_Fun(t *testing.T) { + m := gmap.NewIntStringMap() + + m.GetOrSetFunc(1, getString) + m.GetOrSetFuncLock(2, getString) + gtest.Assert(m.Get(1), "z") + gtest.Assert(m.Get(2), "z") + gtest.Assert(m.SetIfNotExistFunc(1, getString), false) + gtest.Assert(m.SetIfNotExistFuncLock(2, getString), false) +} + +func Test_IntStringMap_Batch(t *testing.T) { + m := gmap.NewIntStringMap() + + m.BatchSet(map[int]string{1: "a", 2: "b",3:"c"}) + m.Iterator(intStringCallBack) + gtest.Assert(m.Map(), map[int]string{1: "a", 2: "b"}) + m.BatchRemove([]int{1, 2}) + gtest.Assert(m.Map(), map[int]interface{}{3: "c"}) +} + +func Test_IntStringMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewIntStringMapFrom(map[int]string{1: "a", 2: "b",3:"c"}) + + m_clone := m.Clone() + m.Remove(1) + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN(1, m_clone.Keys()) + + m_clone.Remove(2) + //修改clone map,原 map 不影响 + gtest.AssertIN(2, m.Keys()) +} +func Test_IntStringMap_Merge(t *testing.T) { + m1 := gmap.NewIntStringMap() + m2 := gmap.NewIntStringMap() + m1.Set(1, "a") + m2.Set(2, "b") + m1.Merge(m2) + gtest.Assert(m1.Map(), map[int]string{1: "a", 2: "b"}) +} diff --git a/g/container/gmap/gmap_z_interface_interface_basic_test.go b/g/container/gmap/gmap_z_interface_interface_basic_test.go index 6f23e4155..ead2dae73 100644 --- a/g/container/gmap/gmap_z_interface_interface_basic_test.go +++ b/g/container/gmap/gmap_z_interface_interface_basic_test.go @@ -17,7 +17,6 @@ func Test_Map_Basic(t *testing.T) { m := gmap.New() m.Set("key1", "val1") gtest.Assert(m.Keys(), []interface{}{"key1"}) - gtest.Assert(m.Values(), []interface{}{"val1"}) gtest.Assert(m.Get("key1"), "val1") gtest.Assert(m.Size(), 1) diff --git a/g/container/gmap/gmap_z_string_bool_test.go b/g/container/gmap/gmap_z_string_bool_test.go new file mode 100644 index 000000000..63b251ed3 --- /dev/null +++ b/g/container/gmap/gmap_z_string_bool_test.go @@ -0,0 +1,85 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + + +func StringBoolCallBack( string, bool) bool { + return true +} +func Test_StringBoolMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewStringBoolMap() + m.Set("a", true) + + gtest.Assert(m.Get("a"), true) + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet("b", false), false) + gtest.Assert(m.SetIfNotExist("b", false), false) + + gtest.Assert(m.SetIfNotExist("c", false), true) + + gtest.Assert(m.Remove("b"), false) + gtest.Assert(m.Contains("b"), false) + + gtest.AssertIN("c", m.Keys()) + gtest.AssertIN("a", m.Keys()) + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewStringBoolMapFrom(map[string]bool{"a": true, "b": false}) + gtest.Assert(m2.Map(), map[string]bool{"a": true, "b": false}) + m3 := gmap.NewStringBoolMapFromArray([]string{"a", "b"}, []bool{true, false}) + gtest.Assert(m3.Map(), map[string]bool{"a": true, "b": false}) + + }) +} +func Test_StringBoolMap_Set_Fun(t *testing.T) { + m := gmap.NewStringBoolMap() + + m.GetOrSetFunc("a", getBool) + m.GetOrSetFuncLock("b", getBool) + gtest.Assert(m.Get("a"), true) + gtest.Assert(m.Get("b"), true) + gtest.Assert(m.SetIfNotExistFunc("a", getBool), false) + gtest.Assert(m.SetIfNotExistFuncLock("b", getBool), false) +} + +func Test_StringBoolMap_Batch(t *testing.T) { + m := gmap.NewStringBoolMap() + + m.BatchSet(map[string]bool{"a": true, "b": false, "c": true}) + m.Iterator(StringBoolCallBack) + gtest.Assert(m.Map(), map[string]bool{"a": true, "b": false, "c": true}) + m.BatchRemove([]string{"a", "b"}) + gtest.Assert(m.Map(), map[string]bool{"c": true}) +} + +func Test_StringBoolMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewStringBoolMapFrom(map[string]bool{"a": true, "b": false}) + + m_clone := m.Clone() + m.Remove("a") + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN("a", m_clone.Keys()) + + m_clone.Remove("b") + //修改clone map,原 map 不影响 + gtest.AssertIN("b", m.Keys()) +} +func Test_StringBoolMap_Merge(t *testing.T) { + m1 := gmap.NewStringBoolMap() + m2 := gmap.NewStringBoolMap() + m1.Set("a", true) + m2.Set("b", false) + m1.Merge(m2) + gtest.Assert(m1.Map(), map[string]bool{"a": true, "b": false}) +} diff --git a/g/container/gmap/gmap_z_string_int_test.go b/g/container/gmap/gmap_z_string_int_test.go new file mode 100644 index 000000000..69892eba1 --- /dev/null +++ b/g/container/gmap/gmap_z_string_int_test.go @@ -0,0 +1,93 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + + +func stringIntCallBack(string, int) bool { + return true +} +func Test_StringIntMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewStringIntMap() + m.Set("a", 1) + + gtest.Assert(m.Get("a"), 1) + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet("b", 2), 2) + gtest.Assert(m.SetIfNotExist("b", 2), false) + + gtest.Assert(m.SetIfNotExist("c", 3), true) + + gtest.Assert(m.Remove("b"), 2) + gtest.Assert(m.Contains("b"), false) + + gtest.AssertIN("c", m.Keys()) + gtest.AssertIN("a", m.Keys()) + gtest.AssertIN(3, m.Values()) + gtest.AssertIN(1, m.Values()) + + m_f := gmap.NewStringIntMap() + m_f.Set("1",2) + m_f.Flip() + gtest.Assert(m_f.Map(),map[string]int{"2":1}) + + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewStringIntMapFrom(map[string]int{"a": 1, "b": 2}) + gtest.Assert(m2.Map(), map[string]int{"a": 1, "b": 2}) + m3 := gmap.NewStringIntMapFromArray([]string{"a","b"}, []int{1, 2}) + gtest.Assert(m3.Map(), map[string]int{"a": 1, "b": 2}) + + }) +} +func Test_StringIntMap_Set_Fun(t *testing.T) { + m := gmap.NewStringIntMap() + + m.GetOrSetFunc("a", getInt) + m.GetOrSetFuncLock("b", getInt) + gtest.Assert(m.Get("a"), 123) + gtest.Assert(m.Get("b"), 123) + gtest.Assert(m.SetIfNotExistFunc("a", getInt), false) + gtest.Assert(m.SetIfNotExistFuncLock("b", getInt), false) +} + +func Test_StringIntMap_Batch(t *testing.T) { + m := gmap.NewStringIntMap() + + m.BatchSet(map[string]int{"a": 1, "b": 2,"c":3}) + m.Iterator(stringIntCallBack) + gtest.Assert(m.Map(), map[string]int{"a": 1, "b": 2,"c":3}) + m.BatchRemove([]string{"a","b"}) + gtest.Assert(m.Map(), map[string]int{"c": 3}) +} + +func Test_StringIntMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewStringIntMapFrom(map[string]int{"a": 1, "b": 2,"c":3}) + + m_clone := m.Clone() + m.Remove("a") + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN("a", m_clone.Keys()) + + m_clone.Remove("b") + //修改clone map,原 map 不影响 + gtest.AssertIN("b", m.Keys()) +} +func Test_StringIntMap_Merge(t *testing.T) { + m1 := gmap.NewStringIntMap() + m2 := gmap.NewStringIntMap() + m1.Set("a", 1) + m2.Set("b", 2) + m1.Merge(m2) + gtest.Assert(m1.Map(),map[string]int{"a": 1, "b": 2}) +} diff --git a/g/container/gmap/gmap_z_string_interface_test.go b/g/container/gmap/gmap_z_string_interface_test.go new file mode 100644 index 000000000..45407c186 --- /dev/null +++ b/g/container/gmap/gmap_z_string_interface_test.go @@ -0,0 +1,90 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + + +func stringInterfaceCallBack(string, interface{}) bool { + return true +} +func Test_StringInterfaceMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewStringInterfaceMap() + m.Set("a", 1) + + gtest.Assert(m.Get("a"), 1) + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet("b", "2"), "2") + gtest.Assert(m.SetIfNotExist("b", "2"), false) + + gtest.Assert(m.SetIfNotExist("c", 3), true) + + gtest.Assert(m.Remove("b"), "2") + gtest.Assert(m.Contains("b"), false) + + gtest.AssertIN("c", m.Keys()) + gtest.AssertIN("a", m.Keys()) + gtest.AssertIN(3, m.Values()) + gtest.AssertIN(1, m.Values()) + + m.Flip() + gtest.Assert(m.Map(), map[string]interface{}{"1": "a", "3": "c"}) + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewStringInterfaceMapFrom(map[string]interface{}{"a": 1, "b": "2"}) + gtest.Assert(m2.Map(), map[string]interface{}{"a": 1, "b": "2"}) + m3 := gmap.NewStringInterfaceMapFromArray([]string{"a", "b"}, []interface{}{1, "2"}) + gtest.Assert(m3.Map(), map[string]interface{}{"a": 1, "b": "2"}) + + }) +} +func Test_StringInterfaceMap_Set_Fun(t *testing.T) { + m := gmap.NewStringInterfaceMap() + + m.GetOrSetFunc("a", getInterface) + m.GetOrSetFuncLock("b", getInterface) + gtest.Assert(m.Get("a"), 123) + gtest.Assert(m.Get("b"), 123) + gtest.Assert(m.SetIfNotExistFunc("a", getInterface), false) + gtest.Assert(m.SetIfNotExistFuncLock("b", getInterface), false) +} + +func Test_StringInterfaceMap_Batch(t *testing.T) { + m := gmap.NewStringInterfaceMap() + + m.BatchSet(map[string]interface{}{"a": 1, "b": "2","c":3}) + m.Iterator(stringInterfaceCallBack) + gtest.Assert(m.Map(), map[string]interface{}{"a": 1, "b": "2","c":3}) + m.BatchRemove([]string{"a","b"}) + gtest.Assert(m.Map(), map[string]interface{}{"c":3}) +} + +func Test_StringInterfaceMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewStringInterfaceMapFrom(map[string]interface{}{"a": 1, "b": "2"}) + + m_clone := m.Clone() + m.Remove("a") + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN("a", m_clone.Keys()) + + m_clone.Remove("b") + //修改clone map,原 map 不影响 + gtest.AssertIN("b", m.Keys()) +} +func Test_StringInterfaceMap_Merge(t *testing.T) { + m1 := gmap.NewStringInterfaceMap() + m2 := gmap.NewStringInterfaceMap() + m1.Set("a", 1) + m2.Set("b", "2") + m1.Merge(m2) + gtest.Assert(m1.Map(), map[string]interface{}{"a": 1, "b": "2"}) +} From 8e7bf1f908c6bb84e8e5a92ab9120db8534d16e4 Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Thu, 11 Apr 2019 17:46:19 +0800 Subject: [PATCH 6/7] =?UTF-8?q?bug=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/gmap_int_string_map.go | 288 +++++++++-------- g/container/gmap/gmap_string_int_map.go | 300 +++++++++--------- g/container/gmap/gmap_string_interface_map.go | 152 ++++----- g/container/gmap/gmap_z_int_string_test.go | 13 +- g/container/gmap/gmap_z_string_int_test.go | 18 +- .../gmap/gmap_z_string_interface_test.go | 9 +- 6 files changed, 387 insertions(+), 393 deletions(-) diff --git a/g/container/gmap/gmap_int_string_map.go b/g/container/gmap/gmap_int_string_map.go index b2bb701c7..f6290f23d 100644 --- a/g/container/gmap/gmap_int_string_map.go +++ b/g/container/gmap/gmap_int_string_map.go @@ -4,12 +4,11 @@ // If a copy of the MIT was not distributed with gm file, // You can obtain one at https://github.com/gogf/gf. - package gmap import ( - "github.com/gogf/gf/g/internal/rwmutex" - "github.com/gogf/gf/g/util/gconv" + "github.com/gogf/gf/g/internal/rwmutex" + "github.com/gogf/gf/g/util/gconv" ) type IntStringMap struct { @@ -20,21 +19,21 @@ type IntStringMap struct { // NewIntStringMap returns an empty IntStringMap object. // The param used to specify whether using map with un-concurrent-safety, // which is false in default, means concurrent-safe. -func NewIntStringMap(unsafe...bool) *IntStringMap { +func NewIntStringMap(unsafe ...bool) *IntStringMap { return &IntStringMap{ - m : make(map[int]string), - mu : rwmutex.New(unsafe...), - } + m: make(map[int]string), + mu: rwmutex.New(unsafe...), + } } // NewIntStringMapFrom returns an IntStringMap object from given map . // Notice that, the param map is a type of pointer, // there might be some concurrent-safe issues when changing the map outside. -func NewIntStringMapFrom(m map[int]string, unsafe...bool) *IntStringMap { - return &IntStringMap{ - m : m, - mu : rwmutex.New(unsafe...), - } +func NewIntStringMapFrom(m map[int]string, unsafe ...bool) *IntStringMap { + return &IntStringMap{ + m: m, + mu: rwmutex.New(unsafe...), + } } // NewIntStringMapFromArray returns an IntStringMap object from given array. @@ -43,37 +42,37 @@ func NewIntStringMapFrom(m map[int]string, unsafe...bool) *IntStringMap { // // If length of is greater than that of , // the corresponding overflow map values will be the default value of its type. -func NewIntStringMapFromArray(keys []int, values []string, unsafe...bool) *IntStringMap { - m := make(map[int]string) - l := len(values) - for i, k := range keys { - if i < l { - m[k] = values[i] - } else { - m[k] = "" - } - } - return &IntStringMap{ - m : m, - mu : rwmutex.New(unsafe...), - } +func NewIntStringMapFromArray(keys []int, values []string, unsafe ...bool) *IntStringMap { + m := make(map[int]string) + l := len(values) + for i, k := range keys { + if i < l { + m[k] = values[i] + } else { + m[k] = "" + } + } + return &IntStringMap{ + m: m, + mu: rwmutex.New(unsafe...), + } } // Iterator iterates the hash map with custom callback function . // If f returns true, then continue iterating; or false to stop. -func (gm *IntStringMap) Iterator(f func (k int, v string) bool) { - gm.mu.RLock() - defer gm.mu.RUnlock() - for k, v := range gm.m { - if !f(k, v) { - break - } - } +func (gm *IntStringMap) Iterator(f func(k int, v string) bool) { + gm.mu.RLock() + defer gm.mu.RUnlock() + for k, v := range gm.m { + if !f(k, v) { + break + } + } } // Clone returns a new hash map with copy of current map data. func (gm *IntStringMap) Clone() *IntStringMap { - return NewIntStringMapFrom(gm.Map(), !gm.mu.IsSafe()) + return NewIntStringMapFrom(gm.Map(), !gm.mu.IsSafe()) } // Map returns a copy of the data of the hash map. @@ -83,7 +82,7 @@ func (gm *IntStringMap) Map() map[int]string { for k, v := range gm.m { m[k] = v } - gm.mu.RUnlock() + gm.mu.RUnlock() return m } @@ -117,40 +116,40 @@ func (gm *IntStringMap) Get(key int) string { // // It returns value with given . func (gm *IntStringMap) doSetWithLockCheck(key int, value string) string { - gm.mu.Lock() - if v, ok := gm.m[key]; ok { - gm.mu.Unlock() - return v - } - gm.m[key] = value - gm.mu.Unlock() - return value + gm.mu.Lock() + if v, ok := gm.m[key]; ok { + gm.mu.Unlock() + return v + } + gm.m[key] = value + gm.mu.Unlock() + return value } // GetOrSet returns the value by key, // or set value with given if not exist and returns this value. func (gm *IntStringMap) GetOrSet(key int, value string) string { - gm.mu.RLock() - v, ok := gm.m[key] - gm.mu.RUnlock() - if !ok { - return gm.doSetWithLockCheck(key, value) - } else { - return v - } + gm.mu.RLock() + v, ok := gm.m[key] + gm.mu.RUnlock() + if !ok { + return gm.doSetWithLockCheck(key, value) + } else { + return v + } } // GetOrSetFunc returns the value by key, // or sets value with return value of callback function if not exist and returns this value. func (gm *IntStringMap) GetOrSetFunc(key int, f func() string) string { - gm.mu.RLock() - v, ok := gm.m[key] - gm.mu.RUnlock() - if !ok { - return gm.doSetWithLockCheck(key, f()) - } else { - return v - } + gm.mu.RLock() + v, ok := gm.m[key] + gm.mu.RUnlock() + if !ok { + return gm.doSetWithLockCheck(key, f()) + } else { + return v + } } // GetOrSetFuncLock returns the value by key, @@ -159,31 +158,31 @@ func (gm *IntStringMap) GetOrSetFunc(key int, f func() string) string { // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function // with mutex.Lock of the hash map. func (gm *IntStringMap) GetOrSetFuncLock(key int, f func() string) string { - gm.mu.RLock() - val, ok := gm.m[key] - gm.mu.RUnlock() - if !ok { - gm.mu.Lock() - defer gm.mu.Unlock() - if v, ok := gm.m[key]; ok { - return v - } - val = f() - gm.m[key] = val - return val - } else { - return val - } + gm.mu.RLock() + val, ok := gm.m[key] + gm.mu.RUnlock() + if !ok { + gm.mu.Lock() + defer gm.mu.Unlock() + if v, ok := gm.m[key]; ok { + return v + } + val = f() + gm.m[key] = val + return val + } else { + return val + } } // SetIfNotExist sets to the map if the does not exist, then return true. // It returns false if exists, and would be ignored. func (gm *IntStringMap) SetIfNotExist(key int, value string) bool { - if !gm.Contains(key) { - gm.doSetWithLockCheck(key, value) - return true - } - return false + if !gm.Contains(key) { + gm.doSetWithLockCheck(key, value) + return true + } + return false } // SetIfNotExistFunc sets value with return value of callback function , then return true. @@ -213,117 +212,116 @@ func (gm *IntStringMap) SetIfNotExistFuncLock(key int, f func() string) bool { return false } - // BatchRemove batch deletes values of the map by keys. func (gm *IntStringMap) BatchRemove(keys []int) { - gm.mu.Lock() - for _, key := range keys { - delete(gm.m, key) - } - gm.mu.Unlock() + gm.mu.Lock() + for _, key := range keys { + delete(gm.m, key) + } + gm.mu.Unlock() } // Remove deletes value from map by given , and return this deleted value. func (gm *IntStringMap) Remove(key int) string { - gm.mu.Lock() - val, exists := gm.m[key] - if exists { - delete(gm.m, key) - } - gm.mu.Unlock() - return val + gm.mu.Lock() + val, exists := gm.m[key] + if exists { + delete(gm.m, key) + } + gm.mu.Unlock() + return val } // Keys returns all keys of the map as a slice. func (gm *IntStringMap) Keys() []int { - gm.mu.RLock() - keys := make([]int, 0) - for key, _ := range gm.m { - keys = append(keys, key) - } - gm.mu.RUnlock() - return keys + gm.mu.RLock() + keys := make([]int, 0) + for key, _ := range gm.m { + keys = append(keys, key) + } + gm.mu.RUnlock() + return keys } // Values returns all values of the map as a slice. func (gm *IntStringMap) Values() []string { - gm.mu.RLock() - vals := make([]string, 0) - for _, val := range gm.m { - vals = append(vals, val) - } - gm.mu.RUnlock() - return vals + gm.mu.RLock() + vals := make([]string, 0) + for _, val := range gm.m { + vals = append(vals, val) + } + gm.mu.RUnlock() + return vals } // Contains checks whether a key exists. // It returns true if the exists, or else false. func (gm *IntStringMap) Contains(key int) bool { - gm.mu.RLock() - _, exists := gm.m[key] - gm.mu.RUnlock() - return exists + gm.mu.RLock() + _, exists := gm.m[key] + gm.mu.RUnlock() + return exists } // Size returns the size of the map. func (gm *IntStringMap) Size() int { - gm.mu.RLock() - length := len(gm.m) - gm.mu.RUnlock() - return length + gm.mu.RLock() + length := len(gm.m) + gm.mu.RUnlock() + return length } // IsEmpty checks whether the map is empty. // It returns true if map is empty, or else false. func (gm *IntStringMap) IsEmpty() bool { - gm.mu.RLock() - empty := len(gm.m) == 0 - gm.mu.RUnlock() - return empty + gm.mu.RLock() + empty := len(gm.m) == 0 + gm.mu.RUnlock() + return empty } // Clear deletes all data of the map, it will remake a new underlying map data map. func (gm *IntStringMap) Clear() { - gm.mu.Lock() - gm.m = make(map[int]string) - gm.mu.Unlock() + gm.mu.Lock() + gm.m = make(map[int]string) + gm.mu.Unlock() } // LockFunc locks writing with given callback function and mutex.Lock. func (gm *IntStringMap) LockFunc(f func(m map[int]string)) { - gm.mu.Lock() - defer gm.mu.Unlock() - f(gm.m) + gm.mu.Lock() + defer gm.mu.Unlock() + f(gm.m) } // RLockFunc locks reading with given callback function and mutex.RLock. func (gm *IntStringMap) RLockFunc(f func(m map[int]string)) { - gm.mu.RLock() - defer gm.mu.RUnlock() - f(gm.m) + gm.mu.RLock() + defer gm.mu.RUnlock() + f(gm.m) } // Flip exchanges key-value of the map, it will change key-value to value-key. func (gm *IntStringMap) Flip() { - gm.mu.Lock() - defer gm.mu.Unlock() - n := make(map[int]string, len(gm.m)) - for k, v := range gm.m { - n[gconv.Int(v)] = gconv.String(k) - } - gm.m = n + gm.mu.Lock() + defer gm.mu.Unlock() + n := make(map[int]string, len(gm.m)) + for k, v := range gm.m { + n[gconv.Int(v)] = gconv.String(k) + } + gm.m = n } // Merge merges two hash maps. // The map will be merged into the map . func (gm *IntStringMap) Merge(other *IntStringMap) { - gm.mu.Lock() - defer gm.mu.Unlock() - if other != gm { - other.mu.RLock() - defer other.mu.RUnlock() - } - for k, v := range other.m { - gm.m[k] = v - } -} \ No newline at end of file + gm.mu.Lock() + defer gm.mu.Unlock() + if other != gm { + other.mu.RLock() + defer other.mu.RUnlock() + } + for k, v := range other.m { + gm.m[k] = v + } +} diff --git a/g/container/gmap/gmap_string_int_map.go b/g/container/gmap/gmap_string_int_map.go index 052d956e3..028f82c74 100644 --- a/g/container/gmap/gmap_string_int_map.go +++ b/g/container/gmap/gmap_string_int_map.go @@ -8,8 +8,8 @@ package gmap import ( - "github.com/gogf/gf/g/internal/rwmutex" - "github.com/gogf/gf/g/util/gconv" + "github.com/gogf/gf/g/internal/rwmutex" + "github.com/gogf/gf/g/util/gconv" ) type StringIntMap struct { @@ -20,21 +20,21 @@ type StringIntMap struct { // NewStringIntMap returns an empty StringIntMap object. // The param used to specify whether using map with un-concurrent-safety, // which is false in default, means concurrent-safe. -func NewStringIntMap(unsafe...bool) *StringIntMap { +func NewStringIntMap(unsafe ...bool) *StringIntMap { return &StringIntMap{ - m : make(map[string]int), - mu : rwmutex.New(unsafe...), - } + m: make(map[string]int), + mu: rwmutex.New(unsafe...), + } } // NewStringIntMapFrom returns an StringIntMap object from given map . // Notice that, the param map is a type of pointer, // there might be some concurrent-safe issues when changing the map outside. -func NewStringIntMapFrom(m map[string]int, unsafe...bool) *StringIntMap { - return &StringIntMap{ - m : m, - mu : rwmutex.New(unsafe...), - } +func NewStringIntMapFrom(m map[string]int, unsafe ...bool) *StringIntMap { + return &StringIntMap{ + m: m, + mu: rwmutex.New(unsafe...), + } } // NewStringIntMapFromArray returns an StringIntMap object from given array. @@ -43,48 +43,48 @@ func NewStringIntMapFrom(m map[string]int, unsafe...bool) *StringIntMap { // // If length of is greater than that of , // the corresponding overflow map values will be the default value of its type. -func NewStringIntMapFromArray(keys []string, values []int, unsafe...bool) *StringIntMap { - m := make(map[string]int) - l := len(values) - for i, k := range keys { - if i < l { - m[k] = values[i] - } else { - m[k] = 0 - } - } - return &StringIntMap{ - m : m, - mu : rwmutex.New(unsafe...), - } +func NewStringIntMapFromArray(keys []string, values []int, unsafe ...bool) *StringIntMap { + m := make(map[string]int) + l := len(values) + for i, k := range keys { + if i < l { + m[k] = values[i] + } else { + m[k] = 0 + } + } + return &StringIntMap{ + m: m, + mu: rwmutex.New(unsafe...), + } } // Iterator iterates the hash map with custom callback function . // If f returns true, then continue iterating; or false to stop. -func (gm *StringIntMap) Iterator(f func (k string, v int) bool) { - gm.mu.RLock() - defer gm.mu.RUnlock() - for k, v := range gm.m { - if !f(k, v) { - break - } - } +func (gm *StringIntMap) Iterator(f func(k string, v int) bool) { + gm.mu.RLock() + defer gm.mu.RUnlock() + for k, v := range gm.m { + if !f(k, v) { + break + } + } } // Clone returns a new hash map with copy of current map data. func (gm *StringIntMap) Clone() *StringIntMap { - return NewStringIntMapFrom(gm.Map(), !gm.mu.IsSafe()) + return NewStringIntMapFrom(gm.Map(), !gm.mu.IsSafe()) } // Map returns a copy of the data of the hash map. func (gm *StringIntMap) Map() map[string]int { - m := make(map[string]int) - gm.mu.RLock() - for k, v := range gm.m { - m[k] = v - } - gm.mu.RUnlock() - return m + m := make(map[string]int) + gm.mu.RLock() + for k, v := range gm.m { + m[k] = v + } + gm.mu.RUnlock() + return m } // Set sets key-value to the hash map. @@ -107,7 +107,7 @@ func (gm *StringIntMap) BatchSet(m map[string]int) { func (gm *StringIntMap) Get(key string) int { gm.mu.RLock() val, _ := gm.m[key] - gm.mu.RUnlock() + gm.mu.RUnlock() return val } @@ -117,41 +117,41 @@ func (gm *StringIntMap) Get(key string) int { // // It returns value with given . func (gm *StringIntMap) doSetWithLockCheck(key string, value int) int { - gm.mu.Lock() - if v, ok := gm.m[key]; ok { - gm.mu.Unlock() - return v - } - gm.m[key] = value - gm.mu.Unlock() - return value + gm.mu.Lock() + if v, ok := gm.m[key]; ok { + gm.mu.Unlock() + return v + } + gm.m[key] = value + gm.mu.Unlock() + return value } // GetOrSet returns the value by key, // or set value with given if not exist and returns this value. func (gm *StringIntMap) GetOrSet(key string, value int) int { - gm.mu.RLock() - v, ok := gm.m[key] - gm.mu.RUnlock() - if !ok { - return gm.doSetWithLockCheck(key, value) - } else { - return v - } + gm.mu.RLock() + v, ok := gm.m[key] + gm.mu.RUnlock() + if !ok { + return gm.doSetWithLockCheck(key, value) + } else { + return v + } } // GetOrSetFunc returns the value by key, // or sets value with return value of callback function if not exist // and returns this value. func (gm *StringIntMap) GetOrSetFunc(key string, f func() int) int { - gm.mu.RLock() - v, ok := gm.m[key] - gm.mu.RUnlock() - if !ok { - return gm.doSetWithLockCheck(key, f()) - } else { - return v - } + gm.mu.RLock() + v, ok := gm.m[key] + gm.mu.RUnlock() + if !ok { + return gm.doSetWithLockCheck(key, f()) + } else { + return v + } } // GetOrSetFuncLock returns the value by key, @@ -161,31 +161,31 @@ func (gm *StringIntMap) GetOrSetFunc(key string, f func() int) int { // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function // with mutex.Lock of the hash map. func (gm *StringIntMap) GetOrSetFuncLock(key string, f func() int) int { - gm.mu.RLock() - val, ok := gm.m[key] - gm.mu.RUnlock() - if !ok { - gm.mu.Lock() - defer gm.mu.Unlock() - if v, ok := gm.m[key]; ok { - return v - } - val = f() - gm.m[key] = val - return val - } else { - return val - } + gm.mu.RLock() + val, ok := gm.m[key] + gm.mu.RUnlock() + if !ok { + gm.mu.Lock() + defer gm.mu.Unlock() + if v, ok := gm.m[key]; ok { + return v + } + val = f() + gm.m[key] = val + return val + } else { + return val + } } // SetIfNotExist sets to the map if the does not exist, then return true. // It returns false if exists, and would be ignored. func (gm *StringIntMap) SetIfNotExist(key string, value int) bool { - if !gm.Contains(key) { - gm.doSetWithLockCheck(key, value) - return true - } - return false + if !gm.Contains(key) { + gm.doSetWithLockCheck(key, value) + return true + } + return false } // SetIfNotExistFunc sets value with return value of callback function , then return true. @@ -217,114 +217,114 @@ func (gm *StringIntMap) SetIfNotExistFuncLock(key string, f func() int) bool { // BatchRemove batch deletes values of the map by keys. func (gm *StringIntMap) BatchRemove(keys []string) { - gm.mu.Lock() - for _, key := range keys { - delete(gm.m, key) - } - gm.mu.Unlock() + gm.mu.Lock() + for _, key := range keys { + delete(gm.m, key) + } + gm.mu.Unlock() } // Remove deletes value from map by given , and return this deleted value. func (gm *StringIntMap) Remove(key string) int { - gm.mu.Lock() - val, exists := gm.m[key] - if exists { - delete(gm.m, key) - } - gm.mu.Unlock() - return val + gm.mu.Lock() + val, exists := gm.m[key] + if exists { + delete(gm.m, key) + } + gm.mu.Unlock() + return val } // Keys returns all keys of the map as a slice. func (gm *StringIntMap) Keys() []string { - gm.mu.RLock() - keys := make([]string, 0) - for key, _ := range gm.m { - keys = append(keys, key) - } - gm.mu.RUnlock() - return keys + gm.mu.RLock() + keys := make([]string, 0) + for key, _ := range gm.m { + keys = append(keys, key) + } + gm.mu.RUnlock() + return keys } // Values returns all values of the map as a slice. func (gm *StringIntMap) Values() []int { - gm.mu.RLock() - vals := make([]int, 0) - for _, val := range gm.m { - vals = append(vals, val) - } - gm.mu.RUnlock() - return vals + gm.mu.RLock() + vals := make([]int, 0) + for _, val := range gm.m { + vals = append(vals, val) + } + gm.mu.RUnlock() + return vals } // Contains checks whether a key exists. // It returns true if the exists, or else false. func (gm *StringIntMap) Contains(key string) bool { - gm.mu.RLock() - _, exists := gm.m[key] - gm.mu.RUnlock() - return exists + gm.mu.RLock() + _, exists := gm.m[key] + gm.mu.RUnlock() + return exists } // Size returns the size of the map. func (gm *StringIntMap) Size() int { - gm.mu.RLock() - length := len(gm.m) - gm.mu.RUnlock() - return length + gm.mu.RLock() + length := len(gm.m) + gm.mu.RUnlock() + return length } // IsEmpty checks whether the map is empty. // It returns true if map is empty, or else false. func (gm *StringIntMap) IsEmpty() bool { - gm.mu.RLock() - empty := len(gm.m) == 0 - gm.mu.RUnlock() - return empty + gm.mu.RLock() + empty := len(gm.m) == 0 + gm.mu.RUnlock() + return empty } // Clear deletes all data of the map, it will remake a new underlying map data map. func (gm *StringIntMap) Clear() { - gm.mu.Lock() - gm.m = make(map[string]int) - gm.mu.Unlock() + gm.mu.Lock() + gm.m = make(map[string]int) + gm.mu.Unlock() } // LockFunc locks writing with given callback function and mutex.Lock. func (gm *StringIntMap) LockFunc(f func(m map[string]int)) { - gm.mu.Lock() - defer gm.mu.Unlock() - f(gm.m) + gm.mu.Lock() + defer gm.mu.Unlock() + f(gm.m) } // RLockFunc locks reading with given callback function and mutex.RLock. func (gm *StringIntMap) RLockFunc(f func(m map[string]int)) { - gm.mu.RLock() - defer gm.mu.RUnlock() - f(gm.m) + gm.mu.RLock() + defer gm.mu.RUnlock() + f(gm.m) } // Flip exchanges key-value of the map, it will change key-value to value-key. func (gm *StringIntMap) Flip() { - gm.mu.Lock() - defer gm.mu.Unlock() - n := make(map[string]int, len(gm.m)) - for k, v := range gm.m { - n[gconv.String(v)] = gconv.Int(k) - } - gm.m = n + gm.mu.Lock() + defer gm.mu.Unlock() + n := make(map[string]int, len(gm.m)) + for k, v := range gm.m { + n[gconv.String(v)] = gconv.Int(k) + } + gm.m = n } // Merge merges two hash maps. // The map will be merged into the map . func (gm *StringIntMap) Merge(other *StringIntMap) { - gm.mu.Lock() - defer gm.mu.Unlock() - if other != gm { - other.mu.RLock() - defer other.mu.RUnlock() - } - for k, v := range other.m { - gm.m[k] = v - } -} \ No newline at end of file + gm.mu.Lock() + defer gm.mu.Unlock() + if other != gm { + other.mu.RLock() + defer other.mu.RUnlock() + } + for k, v := range other.m { + gm.m[k] = v + } +} diff --git a/g/container/gmap/gmap_string_interface_map.go b/g/container/gmap/gmap_string_interface_map.go index 3fab490e9..5c354ea89 100644 --- a/g/container/gmap/gmap_string_interface_map.go +++ b/g/container/gmap/gmap_string_interface_map.go @@ -20,21 +20,21 @@ type StringInterfaceMap struct { // NewStringInterfaceMap returns an empty StringInterfaceMap object. // The param used to specify whether using map with un-concurrent-safety, // which is false in default, means concurrent-safe. -func NewStringInterfaceMap(unsafe...bool) *StringInterfaceMap { +func NewStringInterfaceMap(unsafe ...bool) *StringInterfaceMap { return &StringInterfaceMap{ - m : make(map[string]interface{}), - mu : rwmutex.New(unsafe...), + m: make(map[string]interface{}), + mu: rwmutex.New(unsafe...), } } // NewStringInterfaceMapFrom returns an StringInterfaceMap object from given map . // Notice that, the param map is a type of pointer, // there might be some concurrent-safe issues when changing the map outside. -func NewStringInterfaceMapFrom(m map[string]interface{}, unsafe...bool) *StringInterfaceMap { - return &StringInterfaceMap{ - m : m, - mu : rwmutex.New(unsafe...), - } +func NewStringInterfaceMapFrom(m map[string]interface{}, unsafe ...bool) *StringInterfaceMap { + return &StringInterfaceMap{ + m: m, + mu: rwmutex.New(unsafe...), + } } // NewStringInterfaceMapFromArray returns an StringInterfaceMap object from given array. @@ -43,25 +43,25 @@ func NewStringInterfaceMapFrom(m map[string]interface{}, unsafe...bool) *StringI // // If length of is greater than that of , // the corresponding overflow map values will be the default value of its type. -func NewStringInterfaceMapFromArray(keys []string, values []interface{}, unsafe...bool) *StringInterfaceMap { - m := make(map[string]interface{}) - l := len(values) - for i, k := range keys { - if i < l { - m[k] = values[i] - } else { - m[k] = interface{}(nil) - } - } - return &StringInterfaceMap{ - m : m, - mu : rwmutex.New(unsafe...), - } +func NewStringInterfaceMapFromArray(keys []string, values []interface{}, unsafe ...bool) *StringInterfaceMap { + m := make(map[string]interface{}) + l := len(values) + for i, k := range keys { + if i < l { + m[k] = values[i] + } else { + m[k] = interface{}(nil) + } + } + return &StringInterfaceMap{ + m: m, + mu: rwmutex.New(unsafe...), + } } // Iterator iterates the hash map with custom callback function . // If f returns true, then continue iterating; or false to stop. -func (gm *StringInterfaceMap) Iterator(f func (k string, v interface{}) bool) { +func (gm *StringInterfaceMap) Iterator(f func(k string, v interface{}) bool) { gm.mu.RLock() defer gm.mu.RUnlock() for k, v := range gm.m { @@ -73,18 +73,18 @@ func (gm *StringInterfaceMap) Iterator(f func (k string, v interface{}) bool) { // Clone returns a new hash map with copy of current map data. func (gm *StringInterfaceMap) Clone() *StringInterfaceMap { - return NewStringInterfaceMapFrom(gm.Map(), !gm.mu.IsSafe()) + return NewStringInterfaceMapFrom(gm.Map(), !gm.mu.IsSafe()) } // Map returns a copy of the data of the hash map. func (gm *StringInterfaceMap) Map() map[string]interface{} { - m := make(map[string]interface{}) - gm.mu.RLock() - for k, v := range gm.m { - m[k] = v - } - gm.mu.RUnlock() - return m + m := make(map[string]interface{}) + gm.mu.RLock() + for k, v := range gm.m { + m[k] = v + } + gm.mu.RUnlock() + return m } // Set sets key-value to the hash map. @@ -96,11 +96,11 @@ func (gm *StringInterfaceMap) Set(key string, val interface{}) { // BatchSet batch sets key-values to the hash map. func (gm *StringInterfaceMap) BatchSet(m map[string]interface{}) { - gm.mu.Lock() - for k, v := range m { - gm.m[k] = v - } - gm.mu.Unlock() + gm.mu.Lock() + for k, v := range m { + gm.m[k] = v + } + gm.mu.Unlock() } // Get returns the value by given . @@ -123,37 +123,37 @@ func (gm *StringInterfaceMap) Get(key string) interface{} { func (gm *StringInterfaceMap) doSetWithLockCheck(key string, value interface{}) interface{} { gm.mu.Lock() defer gm.mu.Unlock() - if v, ok := gm.m[key]; ok { - return v - } - if f, ok := value.(func() interface {}); ok { - value = f() - } - if value != nil { - gm.m[key] = value - } - return value + if v, ok := gm.m[key]; ok { + return v + } + if f, ok := value.(func() interface{}); ok { + value = f() + } + if value != nil { + gm.m[key] = value + } + return value } // GetOrSet returns the value by key, // or set value with given if not exist and returns this value. func (gm *StringInterfaceMap) GetOrSet(key string, value interface{}) interface{} { - if v := gm.Get(key); v == nil { - return gm.doSetWithLockCheck(key, value) - } else { - return v - } + if v := gm.Get(key); v == nil { + return gm.doSetWithLockCheck(key, value) + } else { + return v + } } // GetOrSetFunc returns the value by key, // or sets value with return value of callback function if not exist // and returns this value. func (gm *StringInterfaceMap) GetOrSetFunc(key string, f func() interface{}) interface{} { - if v := gm.Get(key); v == nil { - return gm.doSetWithLockCheck(key, f()) - } else { - return v - } + if v := gm.Get(key); v == nil { + return gm.doSetWithLockCheck(key, f()) + } else { + return v + } } // GetOrSetFuncLock returns the value by key, @@ -163,21 +163,21 @@ func (gm *StringInterfaceMap) GetOrSetFunc(key string, f func() interface{}) int // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function // with mutex.Lock of the hash map. func (gm *StringInterfaceMap) GetOrSetFuncLock(key string, f func() interface{}) interface{} { - if v := gm.Get(key); v == nil { - return gm.doSetWithLockCheck(key, f) - } else { - return v - } + if v := gm.Get(key); v == nil { + return gm.doSetWithLockCheck(key, f) + } else { + return v + } } // SetIfNotExist sets to the map if the does not exist, then return true. // It returns false if exists, and would be ignored. func (gm *StringInterfaceMap) SetIfNotExist(key string, value interface{}) bool { - if !gm.Contains(key) { - gm.doSetWithLockCheck(key, value) - return true - } - return false + if !gm.Contains(key) { + gm.doSetWithLockCheck(key, value) + return true + } + return false } // SetIfNotExistFunc sets value with return value of callback function , then return true. @@ -205,11 +205,11 @@ func (gm *StringInterfaceMap) SetIfNotExistFuncLock(key string, f func() interfa // BatchRemove batch deletes values of the map by keys. func (gm *StringInterfaceMap) BatchRemove(keys []string) { - gm.mu.Lock() - for _, key := range keys { - delete(gm.m, key) - } - gm.mu.Unlock() + gm.mu.Lock() + for _, key := range keys { + delete(gm.m, key) + } + gm.mu.Unlock() } // Remove deletes value from map by given , and return this deleted value. @@ -230,7 +230,7 @@ func (gm *StringInterfaceMap) Keys() []string { for key, _ := range gm.m { keys = append(keys, key) } - gm.mu.RUnlock() + gm.mu.RUnlock() return keys } @@ -273,9 +273,9 @@ func (gm *StringInterfaceMap) IsEmpty() bool { // Clear deletes all data of the map, it will remake a new underlying map data map. func (gm *StringInterfaceMap) Clear() { - gm.mu.Lock() - gm.m = make(map[string]interface{}) - gm.mu.Unlock() + gm.mu.Lock() + gm.m = make(map[string]interface{}) + gm.mu.Unlock() } // LockFunc locks writing with given callback function and mutex.Lock. @@ -315,4 +315,4 @@ func (gm *StringInterfaceMap) Merge(other *StringInterfaceMap) { for k, v := range other.m { gm.m[k] = v } -} \ No newline at end of file +} diff --git a/g/container/gmap/gmap_z_int_string_test.go b/g/container/gmap/gmap_z_int_string_test.go index 8c1ddb3f5..386e3a710 100644 --- a/g/container/gmap/gmap_z_int_string_test.go +++ b/g/container/gmap/gmap_z_int_string_test.go @@ -37,10 +37,9 @@ func Test_IntStringMap_Basic(t *testing.T) { //反转之后不成为以下 map,flip 操作只是翻转原 map //gtest.Assert(m.Map(), map[string]int{"a": 1, "c": 3}) m_f := gmap.NewIntStringMap() - m_f.Set(1,"2") + m_f.Set(1, "2") m_f.Flip() - gtest.Assert(m_f.Map(),map[int]string{2:"1"}) - + gtest.Assert(m_f.Map(), map[int]string{2: "1"}) m.Clear() gtest.Assert(m.Size(), 0) @@ -48,7 +47,7 @@ func Test_IntStringMap_Basic(t *testing.T) { m2 := gmap.NewIntStringMapFrom(map[int]string{1: "a", 2: "b"}) gtest.Assert(m2.Map(), map[int]string{1: "a", 2: "b"}) - m3 := gmap.NewIntStringMapFromArray([]int{1, 2}, []string{"a","b"}) + m3 := gmap.NewIntStringMapFromArray([]int{1, 2}, []string{"a", "b"}) gtest.Assert(m3.Map(), map[int]string{1: "a", 2: "b"}) }) @@ -67,16 +66,16 @@ func Test_IntStringMap_Set_Fun(t *testing.T) { func Test_IntStringMap_Batch(t *testing.T) { m := gmap.NewIntStringMap() - m.BatchSet(map[int]string{1: "a", 2: "b",3:"c"}) + m.BatchSet(map[int]string{1: "a", 2: "b", 3: "c"}) m.Iterator(intStringCallBack) - gtest.Assert(m.Map(), map[int]string{1: "a", 2: "b"}) + gtest.Assert(m.Map(), map[int]string{1: "a", 2: "b",3: "c"}) m.BatchRemove([]int{1, 2}) gtest.Assert(m.Map(), map[int]interface{}{3: "c"}) } func Test_IntStringMap_Clone(t *testing.T) { //clone 方法是深克隆 - m := gmap.NewIntStringMapFrom(map[int]string{1: "a", 2: "b",3:"c"}) + m := gmap.NewIntStringMapFrom(map[int]string{1: "a", 2: "b", 3: "c"}) m_clone := m.Clone() m.Remove(1) diff --git a/g/container/gmap/gmap_z_string_int_test.go b/g/container/gmap/gmap_z_string_int_test.go index 69892eba1..7c1050d46 100644 --- a/g/container/gmap/gmap_z_string_int_test.go +++ b/g/container/gmap/gmap_z_string_int_test.go @@ -6,7 +6,6 @@ import ( "testing" ) - func stringIntCallBack(string, int) bool { return true } @@ -33,10 +32,9 @@ func Test_StringIntMap_Basic(t *testing.T) { gtest.AssertIN(1, m.Values()) m_f := gmap.NewStringIntMap() - m_f.Set("1",2) + m_f.Set("1", 2) m_f.Flip() - gtest.Assert(m_f.Map(),map[string]int{"2":1}) - + gtest.Assert(m_f.Map(), map[string]int{"2": 1}) m.Clear() gtest.Assert(m.Size(), 0) @@ -44,7 +42,7 @@ func Test_StringIntMap_Basic(t *testing.T) { m2 := gmap.NewStringIntMapFrom(map[string]int{"a": 1, "b": 2}) gtest.Assert(m2.Map(), map[string]int{"a": 1, "b": 2}) - m3 := gmap.NewStringIntMapFromArray([]string{"a","b"}, []int{1, 2}) + m3 := gmap.NewStringIntMapFromArray([]string{"a", "b"}, []int{1, 2}) gtest.Assert(m3.Map(), map[string]int{"a": 1, "b": 2}) }) @@ -63,16 +61,16 @@ func Test_StringIntMap_Set_Fun(t *testing.T) { func Test_StringIntMap_Batch(t *testing.T) { m := gmap.NewStringIntMap() - m.BatchSet(map[string]int{"a": 1, "b": 2,"c":3}) + m.BatchSet(map[string]int{"a": 1, "b": 2, "c": 3}) m.Iterator(stringIntCallBack) - gtest.Assert(m.Map(), map[string]int{"a": 1, "b": 2,"c":3}) - m.BatchRemove([]string{"a","b"}) + gtest.Assert(m.Map(), map[string]int{"a": 1, "b": 2, "c": 3}) + m.BatchRemove([]string{"a", "b"}) gtest.Assert(m.Map(), map[string]int{"c": 3}) } func Test_StringIntMap_Clone(t *testing.T) { //clone 方法是深克隆 - m := gmap.NewStringIntMapFrom(map[string]int{"a": 1, "b": 2,"c":3}) + m := gmap.NewStringIntMapFrom(map[string]int{"a": 1, "b": 2, "c": 3}) m_clone := m.Clone() m.Remove("a") @@ -89,5 +87,5 @@ func Test_StringIntMap_Merge(t *testing.T) { m1.Set("a", 1) m2.Set("b", 2) m1.Merge(m2) - gtest.Assert(m1.Map(),map[string]int{"a": 1, "b": 2}) + gtest.Assert(m1.Map(), map[string]int{"a": 1, "b": 2}) } diff --git a/g/container/gmap/gmap_z_string_interface_test.go b/g/container/gmap/gmap_z_string_interface_test.go index 45407c186..74e94115d 100644 --- a/g/container/gmap/gmap_z_string_interface_test.go +++ b/g/container/gmap/gmap_z_string_interface_test.go @@ -6,7 +6,6 @@ import ( "testing" ) - func stringInterfaceCallBack(string, interface{}) bool { return true } @@ -60,11 +59,11 @@ func Test_StringInterfaceMap_Set_Fun(t *testing.T) { func Test_StringInterfaceMap_Batch(t *testing.T) { m := gmap.NewStringInterfaceMap() - m.BatchSet(map[string]interface{}{"a": 1, "b": "2","c":3}) + m.BatchSet(map[string]interface{}{"a": 1, "b": "2", "c": 3}) m.Iterator(stringInterfaceCallBack) - gtest.Assert(m.Map(), map[string]interface{}{"a": 1, "b": "2","c":3}) - m.BatchRemove([]string{"a","b"}) - gtest.Assert(m.Map(), map[string]interface{}{"c":3}) + gtest.Assert(m.Map(), map[string]interface{}{"a": 1, "b": "2", "c": 3}) + m.BatchRemove([]string{"a", "b"}) + gtest.Assert(m.Map(), map[string]interface{}{"c": 3}) } func Test_StringInterfaceMap_Clone(t *testing.T) { From 905f46359a0472ba00aeb8b745658e34c8c1fd72 Mon Sep 17 00:00:00 2001 From: Jay <976739120@qq.com> Date: Thu, 11 Apr 2019 17:50:26 +0800 Subject: [PATCH 7/7] =?UTF-8?q?Gmap=20string-string=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/gmap_z_string_string_test.go | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 g/container/gmap/gmap_z_string_string_test.go diff --git a/g/container/gmap/gmap_z_string_string_test.go b/g/container/gmap/gmap_z_string_string_test.go new file mode 100644 index 000000000..443878839 --- /dev/null +++ b/g/container/gmap/gmap_z_string_string_test.go @@ -0,0 +1,90 @@ +package gmap_test + +import ( + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func stringStringCallBack(string, string) bool { + return true +} +func Test_StringStringMap_Basic(t *testing.T) { + gtest.Case(t, func() { + m := gmap.NewStringStringMap() + m.Set("a", "a") + + gtest.Assert(m.Get("a"), "a") + gtest.Assert(m.Size(), 1) + gtest.Assert(m.IsEmpty(), false) + + gtest.Assert(m.GetOrSet("b", "b"), "b") + gtest.Assert(m.SetIfNotExist("b", "b"), false) + + gtest.Assert(m.SetIfNotExist("c", "c"), true) + + gtest.Assert(m.Remove("b"), "b") + gtest.Assert(m.Contains("b"), false) + + gtest.AssertIN("c", m.Keys()) + gtest.AssertIN("a", m.Keys()) + gtest.AssertIN("a", m.Values()) + gtest.AssertIN("c", m.Values()) + + m.Flip() + + gtest.Assert(m.Map(), map[string]string{"a": "a", "c": "c"}) + + m.Clear() + gtest.Assert(m.Size(), 0) + gtest.Assert(m.IsEmpty(), true) + + m2 := gmap.NewStringStringMapFrom(map[string]string{"a": "a", "b": "b"}) + gtest.Assert(m2.Map(), map[string]string{"a": "a", "b": "b"}) + m3 := gmap.NewStringStringMapFromArray([]string{"a", "b"}, []string{"a", "b"}) + gtest.Assert(m3.Map(), map[string]string{"a": "a", "b": "b"}) + + }) +} +func Test_StringStringMap_Set_Fun(t *testing.T) { + m := gmap.NewStringStringMap() + + m.GetOrSetFunc("a", getString) + m.GetOrSetFuncLock("b", getString) + gtest.Assert(m.Get("a"), "z") + gtest.Assert(m.Get("b"), "z") + gtest.Assert(m.SetIfNotExistFunc("a", getString), false) + gtest.Assert(m.SetIfNotExistFuncLock("b", getString), false) +} + +func Test_StringStringMap_Batch(t *testing.T) { + m := gmap.NewStringStringMap() + + m.BatchSet(map[string]string{"a": "a", "b": "b", "c": "c"}) + m.Iterator(stringStringCallBack) + gtest.Assert(m.Map(), map[string]string{"a": "a", "b": "b", "c": "c"}) + m.BatchRemove([]string{"a", "b"}) + gtest.Assert(m.Map(), map[string]string{"c": "c"}) +} + +func Test_StringStringMap_Clone(t *testing.T) { + //clone 方法是深克隆 + m := gmap.NewStringStringMapFrom(map[string]string{"a": "a", "b": "b", "c": "c"}) + + m_clone := m.Clone() + m.Remove("a") + //修改原 map,clone 后的 map 不影响 + gtest.AssertIN("a", m_clone.Keys()) + + m_clone.Remove("b") + //修改clone map,原 map 不影响 + gtest.AssertIN("b", m.Keys()) +} +func Test_StringStringMap_Merge(t *testing.T) { + m1 := gmap.NewStringStringMap() + m2 := gmap.NewStringStringMap() + m1.Set("a", "a") + m2.Set("b", "b") + m1.Merge(m2) + gtest.Assert(m1.Map(), map[string]string{"a": "a", "b": "b"}) +}