diff --git a/g/container/gmap/gmap_link_map.go b/g/container/gmap/gmap_link_map.go index 206037f97..886225cbd 100644 --- a/g/container/gmap/gmap_link_map.go +++ b/g/container/gmap/gmap_link_map.go @@ -12,74 +12,74 @@ import ( "github.com/gogf/gf/g/internal/rwmutex" ) -type LinkMap struct { +type ListMap struct { mu *rwmutex.RWMutex data map[interface{}]*glist.Element list *glist.List } -type gLinkMapNode struct { +type gListMapNode struct { key interface{} value interface{} } -// NewLinkMap returns an empty link map. -// LinkMap is backed by a hash table to store values and doubly-linked list to store ordering. +// NewListMap returns an empty link map. +// ListMap is backed by a hash table to store values and doubly-linked list to store ordering. // The param used to specify whether using map in un-concurrent-safety, // which is false in default, means concurrent-safe. -func NewLinkMap(unsafe ...bool) *LinkMap { - return &LinkMap{ +func NewListMap(unsafe ...bool) *ListMap { + return &ListMap{ mu : rwmutex.New(unsafe...), data : make(map[interface{}]*glist.Element), list : glist.New(true), } } -// NewLinkMapFrom returns a link map from given map . +// NewListMapFrom returns a link map from given map . // Note that, the param map will be set as the underlying data map(no deep copy), // there might be some concurrent-safe issues when changing the map outside. -func NewLinkMapFrom(data map[interface{}]interface{}, unsafe...bool) *LinkMap { - m := NewLinkMap(unsafe...) +func NewListMapFrom(data map[interface{}]interface{}, unsafe...bool) *ListMap { + m := NewListMap(unsafe...) m.Sets(data) return m } // Iterator is alias of IteratorAsc. -func (m *LinkMap) Iterator(f func (key, value interface{}) bool) { +func (m *ListMap) Iterator(f func (key, value interface{}) bool) { m.IteratorAsc(f) } // IteratorAsc iterates the map in ascending order with given callback function . // If returns true, then it continues iterating; or false to stop. -func (m *LinkMap) IteratorAsc(f func (key interface{}, value interface{}) bool) { +func (m *ListMap) IteratorAsc(f func (key interface{}, value interface{}) bool) { m.mu.RLock() defer m.mu.RUnlock() - node := (*gLinkMapNode)(nil) + node := (*gListMapNode)(nil) m.list.IteratorAsc(func(e *glist.Element) bool { - node = e.Value.(*gLinkMapNode) + node = e.Value.(*gListMapNode) return f(node.key, node.value) }) } // IteratorDesc iterates the map in descending order with given callback function . // If returns true, then it continues iterating; or false to stop. -func (m *LinkMap) IteratorDesc(f func (key interface{}, value interface{}) bool) { +func (m *ListMap) IteratorDesc(f func (key interface{}, value interface{}) bool) { m.mu.RLock() defer m.mu.RUnlock() - node := (*gLinkMapNode)(nil) + node := (*gListMapNode)(nil) m.list.IteratorDesc(func(e *glist.Element) bool { - node = e.Value.(*gLinkMapNode) + node = e.Value.(*gListMapNode) return f(node.key, node.value) }) } // Clone returns a new link map with copy of current map data. -func (m *LinkMap) Clone(unsafe ...bool) *LinkMap { - return NewLinkMapFrom(m.Map(), unsafe ...) +func (m *ListMap) Clone(unsafe ...bool) *ListMap { + return NewListMapFrom(m.Map(), unsafe ...) } // Clear deletes all data of the map, it will remake a new underlying data map. -func (m *LinkMap) Clear() { +func (m *ListMap) Clear() { m.mu.Lock() m.data = make(map[interface{}]*glist.Element) m.list = glist.New(true) @@ -87,12 +87,12 @@ func (m *LinkMap) Clear() { } // Map returns a copy of the data of the map. -func (m *LinkMap) Map() map[interface{}]interface{} { +func (m *ListMap) Map() map[interface{}]interface{} { m.mu.RLock() - node := (*gLinkMapNode)(nil) + node := (*gListMapNode)(nil) data := make(map[interface{}]interface{}, len(m.data)) m.list.IteratorAsc(func(e *glist.Element) bool { - node = e.Value.(*gLinkMapNode) + node = e.Value.(*gListMapNode) data[node.key] = node.value return true }) @@ -101,24 +101,24 @@ func (m *LinkMap) Map() map[interface{}]interface{} { } // Set sets key-value to the map. -func (m *LinkMap) Set(key interface{}, value interface{}) { +func (m *ListMap) Set(key interface{}, value interface{}) { m.mu.Lock() if e, ok := m.data[key]; !ok { - m.data[key] = m.list.PushBack(&gLinkMapNode{key, value}) + m.data[key] = m.list.PushBack(&gListMapNode{key, value}) } else { - e.Value = &gLinkMapNode{key, value} + e.Value = &gListMapNode{key, value} } m.mu.Unlock() } // Sets batch sets key-values to the map. -func (m *LinkMap) Sets(data map[interface{}]interface{}) { +func (m *ListMap) Sets(data map[interface{}]interface{}) { m.mu.Lock() for key, value := range data { if e, ok := m.data[key]; !ok { - m.data[key] = m.list.PushBack(&gLinkMapNode{key, value}) + m.data[key] = m.list.PushBack(&gListMapNode{key, value}) } else { - e.Value = &gLinkMapNode{key, value} + e.Value = &gListMapNode{key, value} } } m.mu.Unlock() @@ -126,10 +126,10 @@ func (m *LinkMap) Sets(data map[interface{}]interface{}) { // Search searches the map with given . // Second return parameter is true if key was found, otherwise false. -func (m *LinkMap) Search(key interface{}) (value interface{}, found bool) { +func (m *ListMap) Search(key interface{}) (value interface{}, found bool) { m.mu.RLock() if e, ok := m.data[key]; ok { - value = e.Value.(*gLinkMapNode).value + value = e.Value.(*gListMapNode).value found = ok } m.mu.RUnlock() @@ -137,10 +137,10 @@ func (m *LinkMap) Search(key interface{}) (value interface{}, found bool) { } // Get returns the value by given . -func (m *LinkMap) Get(key interface{}) (value interface{}) { +func (m *ListMap) Get(key interface{}) (value interface{}) { m.mu.RLock() if e, ok := m.data[key]; ok { - value = e.Value.(*gLinkMapNode).value + value = e.Value.(*gListMapNode).value } m.mu.RUnlock() return @@ -155,22 +155,22 @@ func (m *LinkMap) Get(key interface{}) (value interface{}) { // and its return value will be set to the map with . // // It returns value with given . -func (m *LinkMap) doSetWithLockCheck(key interface{}, value interface{}) interface{} { +func (m *ListMap) doSetWithLockCheck(key interface{}, value interface{}) interface{} { m.mu.Lock() defer m.mu.Unlock() if e, ok := m.data[key]; ok { - return e.Value.(*gLinkMapNode).value + return e.Value.(*gListMapNode).value } if f, ok := value.(func() interface {}); ok { value = f() } - m.data[key] = m.list.PushBack(&gLinkMapNode{key, value}) + m.data[key] = m.list.PushBack(&gListMapNode{key, value}) return value } // GetOrSet returns the value by key, // or set value with given if not exist and returns this value. -func (m *LinkMap) GetOrSet(key interface{}, value interface{}) interface{} { +func (m *ListMap) GetOrSet(key interface{}, value interface{}) interface{} { if v, ok := m.Search(key); !ok { return m.doSetWithLockCheck(key, value) } else { @@ -181,7 +181,7 @@ func (m *LinkMap) GetOrSet(key interface{}, value interface{}) interface{} { // GetOrSetFunc returns the value by key, // or sets value with return value of callback function if not exist // and returns this value. -func (m *LinkMap) GetOrSetFunc(key interface{}, f func() interface{}) interface{} { +func (m *ListMap) GetOrSetFunc(key interface{}, f func() interface{}) interface{} { if v, ok := m.Search(key); !ok { return m.doSetWithLockCheck(key, f()) } else { @@ -195,7 +195,7 @@ func (m *LinkMap) GetOrSetFunc(key interface{}, f func() interface{}) interface{ // // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function // with mutex.Lock of the map. -func (m *LinkMap) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} { +func (m *ListMap) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} { if v, ok := m.Search(key); !ok { return m.doSetWithLockCheck(key, f) } else { @@ -205,31 +205,31 @@ func (m *LinkMap) GetOrSetFuncLock(key interface{}, f func() interface{}) interf // GetVar returns a gvar.Var with the value by given . // The returned gvar.Var is un-concurrent safe. -func (m *LinkMap) GetVar(key interface{}) *gvar.Var { +func (m *ListMap) GetVar(key interface{}) *gvar.Var { return gvar.New(m.Get(key), true) } // GetVarOrSet returns a gvar.Var with result from GetVarOrSet. // The returned gvar.Var is un-concurrent safe. -func (m *LinkMap) GetVarOrSet(key interface{}, value interface{}) *gvar.Var { +func (m *ListMap) GetVarOrSet(key interface{}, value interface{}) *gvar.Var { return gvar.New(m.GetOrSet(key, value), true) } // GetVarOrSetFunc returns a gvar.Var with result from GetOrSetFunc. // The returned gvar.Var is un-concurrent safe. -func (m *LinkMap) GetVarOrSetFunc(key interface{}, f func() interface{}) *gvar.Var { +func (m *ListMap) GetVarOrSetFunc(key interface{}, f func() interface{}) *gvar.Var { return gvar.New(m.GetOrSetFunc(key, f), true) } // GetVarOrSetFuncLock returns a gvar.Var with result from GetOrSetFuncLock. // The returned gvar.Var is un-concurrent safe. -func (m *LinkMap) GetVarOrSetFuncLock(key interface{}, f func() interface{}) *gvar.Var { +func (m *ListMap) GetVarOrSetFuncLock(key interface{}, f func() interface{}) *gvar.Var { return gvar.New(m.GetOrSetFuncLock(key, f), true) } // SetIfNotExist sets to the map if the does not exist, then return true. // It returns false if exists, and would be ignored. -func (m *LinkMap) SetIfNotExist(key interface{}, value interface{}) bool { +func (m *ListMap) SetIfNotExist(key interface{}, value interface{}) bool { if !m.Contains(key) { m.doSetWithLockCheck(key, value) return true @@ -239,7 +239,7 @@ func (m *LinkMap) SetIfNotExist(key interface{}, value interface{}) bool { // SetIfNotExistFunc sets value with return value of callback function , then return true. // It returns false if exists, and would be ignored. -func (m *LinkMap) SetIfNotExistFunc(key interface{}, f func() interface{}) bool { +func (m *ListMap) SetIfNotExistFunc(key interface{}, f func() interface{}) bool { if !m.Contains(key) { m.doSetWithLockCheck(key, f()) return true @@ -252,7 +252,7 @@ func (m *LinkMap) SetIfNotExistFunc(key interface{}, f func() interface{}) bool // // SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that // it executes function with mutex.Lock of the map. -func (m *LinkMap) SetIfNotExistFuncLock(key interface{}, f func() interface{}) bool { +func (m *ListMap) SetIfNotExistFuncLock(key interface{}, f func() interface{}) bool { if !m.Contains(key) { m.doSetWithLockCheck(key, f) return true @@ -261,10 +261,10 @@ func (m *LinkMap) SetIfNotExistFuncLock(key interface{}, f func() interface{}) b } // Remove deletes value from map by given , and return this deleted value. -func (m *LinkMap) Remove(key interface{}) (value interface{}) { +func (m *ListMap) Remove(key interface{}) (value interface{}) { m.mu.Lock() if e, ok := m.data[key]; ok { - value = e.Value.(*gLinkMapNode).value + value = e.Value.(*gListMapNode).value delete(m.data, key) m.list.Remove(e) } @@ -273,7 +273,7 @@ func (m *LinkMap) Remove(key interface{}) (value interface{}) { } // Removes batch deletes values of the map by keys. -func (m *LinkMap) Removes(keys []interface{}) { +func (m *ListMap) Removes(keys []interface{}) { m.mu.Lock() for _, key := range keys { if e, ok := m.data[key]; ok { @@ -285,12 +285,12 @@ func (m *LinkMap) Removes(keys []interface{}) { } // Keys returns all keys of the map as a slice in ascending order. -func (m *LinkMap) Keys() []interface{} { +func (m *ListMap) Keys() []interface{} { m.mu.RLock() keys := make([]interface{}, m.list.Len()) index := 0 m.list.IteratorAsc(func(e *glist.Element) bool { - keys[index] = e.Value.(*gLinkMapNode).key + keys[index] = e.Value.(*gListMapNode).key index++ return true }) @@ -299,12 +299,12 @@ func (m *LinkMap) Keys() []interface{} { } // Values returns all values of the map as a slice. -func (m *LinkMap) Values() []interface{} { +func (m *ListMap) Values() []interface{} { m.mu.RLock() values := make([]interface{}, m.list.Len()) index := 0 m.list.IteratorAsc(func(e *glist.Element) bool { - values[index] = e.Value.(*gLinkMapNode).value + values[index] = e.Value.(*gListMapNode).value index++ return true }) @@ -314,7 +314,7 @@ func (m *LinkMap) Values() []interface{} { // Contains checks whether a key exists. // It returns true if the exists, or else false. -func (m *LinkMap) Contains(key interface{}) (ok bool) { +func (m *ListMap) Contains(key interface{}) (ok bool) { m.mu.RLock() _, ok = m.data[key] m.mu.RUnlock() @@ -322,7 +322,7 @@ func (m *LinkMap) Contains(key interface{}) (ok bool) { } // Size returns the size of the map. -func (m *LinkMap) Size() (size int) { +func (m *ListMap) Size() (size int) { m.mu.RLock() size = len(m.data) m.mu.RUnlock() @@ -331,12 +331,12 @@ func (m *LinkMap) Size() (size int) { // IsEmpty checks whether the map is empty. // It returns true if map is empty, or else false. -func (m *LinkMap) IsEmpty() bool { +func (m *ListMap) IsEmpty() bool { return m.Size() == 0 } // Flip exchanges key-value of the map to value-key. -func (m *LinkMap) Flip() { +func (m *ListMap) Flip() { data := m.Map() m.Clear() for key, value := range data { @@ -346,20 +346,20 @@ func (m *LinkMap) Flip() { // Merge merges two link maps. // The map will be merged into the map . -func (m *LinkMap) Merge(other *LinkMap) { +func (m *ListMap) Merge(other *ListMap) { m.mu.Lock() defer m.mu.Unlock() if other != m { other.mu.RLock() defer other.mu.RUnlock() } - node := (*gLinkMapNode)(nil) + node := (*gListMapNode)(nil) other.list.IteratorAsc(func(e *glist.Element) bool { - node = e.Value.(*gLinkMapNode) + node = e.Value.(*gListMapNode) if e, ok := m.data[node.key]; !ok { - m.data[node.key] = m.list.PushBack(&gLinkMapNode{node.key, node.value}) + m.data[node.key] = m.list.PushBack(&gListMapNode{node.key, node.value}) } else { - e.Value = &gLinkMapNode{node.key, node.value} + e.Value = &gListMapNode{node.key, node.value} } return true }) diff --git a/g/container/gmap/gmap_z_bench_safe_test.go b/g/container/gmap/gmap_z_bench_safe_test.go index a8a8fa0d3..e40af2596 100644 --- a/g/container/gmap/gmap_z_bench_safe_test.go +++ b/g/container/gmap/gmap_z_bench_safe_test.go @@ -6,21 +6,22 @@ // go test *.go -bench=".*" -benchmem -package gmap +package gmap_test import ( - "testing" + "github.com/gogf/gf/g/container/gmap" + "testing" "strconv" ) -var iim = NewIntIntMap() -var iifm = NewIntAnyMap() -var ism = NewIntStrMap() -var ififm = New() -var sim = NewStrIntMap() -var sifm = NewStrAnyMap() -var ssm = NewStrStrMap() +var ififm = gmap.New() +var iim = gmap.NewIntIntMap() +var iifm = gmap.NewIntAnyMap() +var ism = gmap.NewIntStrMap() +var sim = gmap.NewStrIntMap() +var sifm = gmap.NewStrAnyMap() +var ssm = gmap.NewStrStrMap() func Benchmark_IntIntMap_Set(b *testing.B) { for i := 0; i < b.N; i++ { diff --git a/g/container/gmap/gmap_z_bench_unsafe_test.go b/g/container/gmap/gmap_z_bench_unsafe_test.go index b9ffeceae..5991c408e 100644 --- a/g/container/gmap/gmap_z_bench_unsafe_test.go +++ b/g/container/gmap/gmap_z_bench_unsafe_test.go @@ -6,21 +6,21 @@ // go test *.go -bench=".*" -benchmem -package gmap +package gmap_test import ( - "testing" + "github.com/gogf/gf/g/container/gmap" + "testing" "strconv" ) - -var iimUnsafe = NewIntIntMap(true) -var iifmUnsafe = NewIntAnyMap(true) -var ismUnsafe = NewIntStrMap(true) -var ififmUnsafe = New(true) -var simUnsafe = NewStrIntMap(true) -var sifmUnsafe = NewStrAnyMap(true) -var ssmUnsafe = NewStrStrMap(true) +var ififmUnsafe = gmap.New(true) +var iimUnsafe = gmap.NewIntIntMap(true) +var iifmUnsafe = gmap.NewIntAnyMap(true) +var ismUnsafe = gmap.NewIntStrMap(true) +var simUnsafe = gmap.NewStrIntMap(true) +var sifmUnsafe = gmap.NewStrAnyMap(true) +var ssmUnsafe = gmap.NewStrStrMap(true) // 写入性能测试 diff --git a/g/container/gmap/gmap_z_link_map_test.go b/g/container/gmap/gmap_z_link_map_test.go index 0fc22e7aa..312e37cf5 100644 --- a/g/container/gmap/gmap_z_link_map_test.go +++ b/g/container/gmap/gmap_z_link_map_test.go @@ -13,9 +13,9 @@ import ( "testing" ) -func Test_Link_Map_Basic(t *testing.T) { +func Test_List_Map_Basic(t *testing.T) { gtest.Case(t, func() { - m := gmap.NewLinkMap() + m := gmap.NewListMap() m.Set("key1", "val1") gtest.Assert(m.Keys(), []interface{}{"key1"}) @@ -43,12 +43,12 @@ func Test_Link_Map_Basic(t *testing.T) { gtest.Assert(m.Size(), 0) gtest.Assert(m.IsEmpty(), true) - m2 := gmap.NewLinkMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) + m2 := gmap.NewListMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"}) }) } -func Test_Link_Map_Set_Fun(t *testing.T) { - m := gmap.NewLinkMap() +func Test_List_Map_Set_Fun(t *testing.T) { + m := gmap.NewListMap() m.GetOrSetFunc("fun", getValue) m.GetOrSetFuncLock("funlock", getValue) gtest.Assert(m.Get("funlock"), 3) @@ -58,17 +58,17 @@ func Test_Link_Map_Set_Fun(t *testing.T) { gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false) } -func Test_Link_Map_Batch(t *testing.T) { - m := gmap.NewLinkMap() +func Test_List_Map_Batch(t *testing.T) { + m := gmap.NewListMap() m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}) gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}) m.Removes([]interface{}{"key1", 1}) gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"}) } -func Test_Link_Map_Iterator(t *testing.T){ +func Test_List_Map_Iterator(t *testing.T){ expect :=map[interface{}]interface{}{1: 1, "key1": "val1"} - m := gmap.NewLinkMapFrom(expect) + m := gmap.NewListMapFrom(expect) m.Iterator(func(k interface{}, v interface{}) bool { gtest.Assert(expect[k], v) return true @@ -88,9 +88,9 @@ func Test_Link_Map_Iterator(t *testing.T){ gtest.Assert(j, 1) } -func Test_Link_Map_Clone(t *testing.T) { +func Test_List_Map_Clone(t *testing.T) { //clone 方法是深克隆 - m := gmap.NewLinkMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) + m := gmap.NewListMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"}) m_clone := m.Clone() m.Remove(1) //修改原 map,clone 后的 map 不影响 @@ -101,17 +101,17 @@ func Test_Link_Map_Clone(t *testing.T) { gtest.AssertIN("key1", m.Keys()) } -func Test_Link_Map_Basic_Merge(t *testing.T) { - m1 := gmap.NewLinkMap() - m2 := gmap.NewLinkMap() +func Test_List_Map_Basic_Merge(t *testing.T) { + m1 := gmap.NewListMap() + m2 := gmap.NewListMap() m1.Set("key1", "val1") m2.Set("key2", "val2") m1.Merge(m2) gtest.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"}) } -func Test_Link_Map_Order(t *testing.T) { - m := gmap.NewLinkMap() +func Test_List_Map_Order(t *testing.T) { + m := gmap.NewListMap() m.Set("k1", "v1") m.Set("k2", "v2") m.Set("k3", "v3") diff --git a/g/container/gtree/gtree_avltree.go b/g/container/gtree/gtree_avltree.go index a72ad9bbb..f6833871e 100644 --- a/g/container/gtree/gtree_avltree.go +++ b/g/container/gtree/gtree_avltree.go @@ -388,10 +388,6 @@ func (tree *AVLTree) Print() { fmt.Println(tree.String()) } -func (node *AVLTreeNode) String() string { - return fmt.Sprintf("%v", node.Key) -} - // Map returns all key-value items as map. func (tree *AVLTree) Map() map[interface{}]interface{} { m := make(map[interface{}]interface{}, tree.Size()) @@ -692,7 +688,7 @@ func output(node *AVLTreeNode, prefix string, isTail bool, str *string) { } else { *str += "┌── " } - *str += node.String() + "\n" + *str += fmt.Sprintf("%v\n", node.Key) if node.children[0] != nil { newPrefix := prefix if isTail { diff --git a/g/container/gtree/gtree_btree.go b/g/container/gtree/gtree_btree.go index f06c9b945..57fd061f3 100644 --- a/g/container/gtree/gtree_btree.go +++ b/g/container/gtree/gtree_btree.go @@ -371,10 +371,6 @@ func (tree *BTree) Print() { fmt.Println(tree.String()) } -func (entry *BTreeEntry) String() string { - return fmt.Sprintf("%v", entry.Key) -} - // Iterator is alias of IteratorAsc. func (tree *BTree) Iterator(f func (key, value interface{}) bool) { tree.IteratorAsc(f) diff --git a/g/container/gtree/gtree_redblacktree.go b/g/container/gtree/gtree_redblacktree.go index 81e314454..ed8d16bf4 100644 --- a/g/container/gtree/gtree_redblacktree.go +++ b/g/container/gtree/gtree_redblacktree.go @@ -546,10 +546,6 @@ func (tree *RedBlackTree) Print() { fmt.Println(tree.String()) } -func (node *RedBlackTreeNode) String() string { - return fmt.Sprintf("%v", node.Key) -} - // Search searches the tree with given . // Second return parameter is true if key was found, otherwise false. func (tree *RedBlackTree) Search(key interface{}) (value interface{}, found bool) { @@ -600,7 +596,7 @@ func (tree *RedBlackTree) output(node *RedBlackTreeNode, prefix string, isTail b } else { *str += "┌── " } - *str += node.String() + "\n" + *str += fmt.Sprintf("%v\n", node.Key) if node.left != nil { newPrefix := prefix if isTail { diff --git a/geg/container/gmap/gmap_order.go b/geg/container/gmap/gmap_order.go new file mode 100644 index 000000000..a41469f87 --- /dev/null +++ b/geg/container/gmap/gmap_order.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/util/gutil" +) + +func main() { + array := g.Slice{2, 3, 1, 5, 4, 6, 8, 7, 9} + hashMap := gmap.New(true) + linkMap := gmap.NewLinkMap(true) + treeMap := gmap.NewTreeMap(gutil.ComparatorInt, true) + for _, v := range array { + hashMap.Set(v, v) + } + for _, v := range array { + linkMap.Set(v, v) + } + for _, v := range array { + treeMap.Set(v, v) + } + fmt.Println("HashMap Keys:", hashMap.Keys()) + fmt.Println("HashMap Values:", hashMap.Values()) + fmt.Println("LinkMap Keys:", linkMap.Keys()) + fmt.Println("LinkMap Values:", linkMap.Values()) + fmt.Println("TreeMap Keys:", treeMap.Keys()) + fmt.Println("TreeMap Values:", treeMap.Values()) +} diff --git a/geg/container/gtree/gtree_avltree.go b/geg/container/gtree/gtree_avltree.go index 231fe53b4..ef99b43e6 100644 --- a/geg/container/gtree/gtree_avltree.go +++ b/geg/container/gtree/gtree_avltree.go @@ -3,17 +3,24 @@ package main import ( "fmt" "github.com/gogf/gf/g/container/gtree" + "github.com/gogf/gf/g/util/gutil" ) func main() { - tree := gtree.NewAVLTree(func(v1, v2 interface{}) int { - return v1.(int) - v2.(int) - }) + tree := gtree.NewAVLTree(gutil.ComparatorInt) for i := 0; i < 10; i++ { tree.Set(i, i*10) } - fmt.Println(tree.String()) - tree.Remove(1) + // 打印树形 + tree.Print() + // 前序遍历 + fmt.Println("ASC:") + tree.IteratorAsc(func(key, value interface{}) bool { + fmt.Println(key, value) + return true + }) + // 后续遍历 + fmt.Println("DESC:") tree.IteratorDesc(func(key, value interface{}) bool { fmt.Println(key, value) return true diff --git a/geg/container/gtree/gtree_redblackmap.go b/geg/container/gtree/gtree_redblackmap.go new file mode 100644 index 000000000..b95a16ec0 --- /dev/null +++ b/geg/container/gtree/gtree_redblackmap.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + "github.com/gogf/gf/g/container/gtree" + "github.com/gogf/gf/g/util/gutil" +) + +func main() { + m := gtree.NewRedBlackTree(gutil.ComparatorInt) + + // 设置键值对 + for i := 0; i < 10; i++ { + m.Set(i, i*10) + } + // 查询大小 + fmt.Println(m.Size()) + // 批量设置键值对(不同的数据类型对象参数不同) + m.Sets(map[interface{}]interface{}{ + 10: 10, + 11: 11, + }) + fmt.Println(m.Size()) + + // 查询是否存在 + fmt.Println(m.Contains(1)) + + // 查询键值 + fmt.Println(m.Get(1)) + + // 删除数据项 + m.Remove(9) + fmt.Println(m.Size()) + + // 批量删除 + m.Removes([]interface{}{10, 11}) + fmt.Println(m.Size()) + + // 当前键名列表(随机排序) + fmt.Println(m.Keys()) + // 当前键值列表(随机排序) + fmt.Println(m.Values()) + + // 查询键名,当键值不存在时,写入给定的默认值 + fmt.Println(m.GetOrSet(100, 100)) + + // 删除键值对,并返回对应的键值 + fmt.Println(m.Remove(100)) + + // 遍历map + m.IteratorAsc(func(k interface{}, v interface{}) bool { + fmt.Printf("%v:%v ", k, v) + return true + }) + fmt.Println() + + // 清空map + m.Clear() + + // 判断map是否为空 + fmt.Println(m.IsEmpty()) +} diff --git a/geg/container/gtree/gtree_redblacktree.go b/geg/container/gtree/gtree_redblacktree.go index 58ad1af39..6691c1a4d 100644 --- a/geg/container/gtree/gtree_redblacktree.go +++ b/geg/container/gtree/gtree_redblacktree.go @@ -8,8 +8,8 @@ func main() { tree := gtree.NewRedBlackTree(func(v1, v2 interface{}) int { return v1.(int) - v2.(int) }) - for i := 0; i < 20; i++ { - tree.Set(i, i*10) + for i := 0; i < 10; i++ { + tree.Set(i, i) } tree.Print() tree.Flip()