From 6731e53d7c5eff37ee677018ebc52cb7bf7edd9b Mon Sep 17 00:00:00 2001 From: charlie <3140647@qq.com> Date: Thu, 12 May 2022 09:35:20 +0800 Subject: [PATCH] maps --- maps/concurrent_map.go | 27 +++++++++++++++++++++++++++ maps/hash_map.go | 31 +++++++++++++++++++++++++++++-- maps/map.go | 28 +++++++++++++++++++++------- maps/map_test.go | 9 +++++++++ maps/rwlock_map.go | 25 +++++++++++++++++++++++-- maps/sort_map.go | 26 +++++++++++++++++--------- 6 files changed, 126 insertions(+), 20 deletions(-) diff --git a/maps/concurrent_map.go b/maps/concurrent_map.go index d0e03d6..c3c794b 100644 --- a/maps/concurrent_map.go +++ b/maps/concurrent_map.go @@ -60,6 +60,33 @@ func (m *ConcurrnetMap[K, V]) Iter() <-chan *Entry[K, V] { return ch } +func (m *ConcurrnetMap[K, V]) Keys() []K { + keys := make([]K, m.Count()) + for _, b := range m.buckets { + keys = append(keys, b.Keys()...) + } + + return keys +} + +func (m *ConcurrnetMap[K, V]) Values() []V { + values := make([]V, 0, m.Count()) + for _, v := range m.buckets { + values = append(values, v.Values()...) + } + + return values +} + +func (m *ConcurrnetMap[K, V]) ToMap() map[K]V { + mm := make(map[K]V, m.Count()) + for _, v := range m.buckets { + mm = Merge(mm, v.ToMap()) + } + + return mm +} + func (m *ConcurrnetMap[K, V]) ForEach(f func(K, V)) { var wg sync.WaitGroup diff --git a/maps/hash_map.go b/maps/hash_map.go index d3a04b4..2e893db 100644 --- a/maps/hash_map.go +++ b/maps/hash_map.go @@ -12,8 +12,8 @@ func NewHashMap[K constraints.Ordered, V any]() *hashMap[K, V] { return &hashMap[K, V]{m: make(map[K]V)} } -func newHashMap[K constraints.Ordered, V any](m map[K]V) *hashMap[K, V] { - return &hashMap[K, V]{m: m} +func newHashMap[K constraints.Ordered, V any](maps ...map[K]V) *hashMap[K, V] { + return &hashMap[K, V]{m: Merge(maps...)} } func (m *hashMap[K, V]) Set(key K, value V) { @@ -56,6 +56,33 @@ func (m *hashMap[K, V]) ForEach(f func(K, V)) { } } +func (m *hashMap[K, V]) Keys() []K { + keys := make([]K, 0, m.Count()) + for k := range m.m { + keys = append(keys, k) + } + + return keys +} + +func (m *hashMap[K, V]) Values() []V { + values := make([]V, 0, m.Count()) + for _, v := range m.m { + values = append(values, v) + } + + return values +} + +func (m *hashMap[K, V]) ToMap() map[K]V { + mm := make(map[K]V, m.Count()) + for k, v := range m.m { + mm[k] = v + } + + return mm +} + func (m *hashMap[K, V]) Clear() { m.m = make(map[K]V) } diff --git a/maps/map.go b/maps/map.go index 41bde33..20a80e7 100644 --- a/maps/map.go +++ b/maps/map.go @@ -3,13 +3,16 @@ package maps import "golang.org/x/exp/constraints" type Map[K constraints.Ordered, V any] interface { - Set(key K, value V) - Get(key K) (value V, ok bool) - Exist(key K) bool - Delete(key K) - Clone() Map[K, V] - Clear() - Count() int + Set(key K, value V) // 设置值 + Get(key K) (value V, ok bool) // 获取值 + Exist(key K) bool // 键是否存在 + Delete(key K) // 删除值 + Keys() []K // 获取所有键 + Values() []V // 获取所有值 + ToMap() map[K]V // 转换为map + Clone() Map[K, V] // 复制 + Clear() // 清空 + Count() int // 数量 Iter() <-chan *Entry[K, V] ForEach(f func(K, V)) } @@ -18,3 +21,14 @@ type Entry[K constraints.Ordered, V any] struct { Key K Value V } + +func Merge[K comparable, V any](mm ...map[K]V) map[K]V { + ret := make(map[K]V) + for _, m := range mm { + for k, v := range m { + ret[k] = v + } + } + + return ret +} diff --git a/maps/map_test.go b/maps/map_test.go index 6119f26..4eda72f 100644 --- a/maps/map_test.go +++ b/maps/map_test.go @@ -16,3 +16,12 @@ func TestHashMap(t *testing.T) { _ = m } + +func TestIter(t *testing.T) { + m := maps.NewHashMap[string, string]() + m.Set("abc", "abc") + + for e := range m.Iter() { + t.Log(e.Key, e.Value) + } +} diff --git a/maps/rwlock_map.go b/maps/rwlock_map.go index cb2d0cb..96ee914 100644 --- a/maps/rwlock_map.go +++ b/maps/rwlock_map.go @@ -13,8 +13,9 @@ type rw_map[K constraints.Ordered, V any] struct { mu sync.RWMutex } -func NewRWMap[K constraints.Ordered, V any]() *rw_map[K, V] { - return &rw_map[K, V]{} +func NewRWMap[K constraints.Ordered, V any](maps ...map[K]V) *rw_map[K, V] { + merged := Merge(maps...) + return &rw_map[K, V]{m: newHashMap(merged)} } func newRWMap[K constraints.Ordered, V any](m Map[K, V]) *rw_map[K, V] { @@ -41,6 +42,26 @@ func (m *rw_map[K, V]) Delete(key K) { m.m.Delete(key) } +func (m *rw_map[K, V]) Keys() []K { + m.mu.RLock() + defer m.mu.RUnlock() + return m.m.Keys() +} + +func (m *rw_map[K, V]) Values() []V { + m.mu.RLock() + defer m.mu.RUnlock() + + return m.m.Values() +} + +func (m *rw_map[K, V]) ToMap() map[K]V { + m.mu.RLock() + defer m.mu.RUnlock() + + return m.m.ToMap() +} + func (m *rw_map[K, V]) Exist(key K) bool { return m.m.Exist(key) } diff --git a/maps/sort_map.go b/maps/sort_map.go index d1388db..d7938bb 100644 --- a/maps/sort_map.go +++ b/maps/sort_map.go @@ -23,12 +23,17 @@ type sorted_map[K constraints.Ordered, V any] struct { maps Map[K, V] } -func NewSortedMap[K constraints.Ordered, V any]() *sorted_map[K, V] { - return &sorted_map[K, V]{keys: make([]K, 0), maps: NewHashMap[K, V]()} +func NewSortedMap[K constraints.Ordered, V any](maps ...map[K]V) *sorted_map[K, V] { + merged := Merge(maps...) + return &sorted_map[K, V]{ + keys: keys(merged), + maps: newHashMap(merged), + } } func NewSortedByMap[K constraints.Ordered, V any](m Map[K, V]) *sorted_map[K, V] { - return &sorted_map[K, V]{maps: m, keys: getKeys(m)} + + return &sorted_map[K, V]{maps: m, keys: m.Keys()} } func (m *sorted_map[K, V]) Get(key K) (V, bool) { @@ -61,7 +66,7 @@ func (m *sorted_map[K, V]) Clear() { } func (m *sorted_map[K, V]) Clone() Map[K, V] { - return &sorted_map[K, V]{maps: m.maps.Clone(), keys: getKeys(m.maps)} + return &sorted_map[K, V]{maps: m.maps.Clone(), keys: m.Keys()} } func (m *sorted_map[K, V]) Iter() <-chan *Entry[K, V] { @@ -113,6 +118,10 @@ func (s *sorted_map[K, V]) Values() []V { return ret } +func (s *sorted_map[K, V]) ToMap() map[K]V { + return s.maps.ToMap() +} + func (m *sorted_map[K, V]) String() string { return fmt.Sprintf("map[%s]", m.Join(" ", func(k K, v V) string { return fmt.Sprintf("%v:%v", k, v) @@ -142,12 +151,11 @@ func (m *sorted_map[K, V]) Desc() SortedMap[K, V] { } } -func getKeys[K constraints.Ordered, V any](m Map[K, V]) []K { - keys := make([]K, 0, m.Count()) - - m.ForEach(func(k K, v V) { +func keys[K comparable, V any](m map[K]V) []K { + keys := make([]K, 0, len(m)) + for k := range m { keys = append(keys, k) - }) + } return keys }