1
0
mirror of https://github.com/charlienet/go-mixed.git synced 2025-07-17 16:12:42 +08:00
This commit is contained in:
2022-05-12 11:32:03 +08:00
parent 7930a64e59
commit 08309e4a49
7 changed files with 85 additions and 37 deletions

View File

@ -12,12 +12,12 @@ import (
var defaultNumOfBuckets = runtime.GOMAXPROCS(runtime.NumCPU())
type ConcurrnetMap[K constraints.Ordered, V any] struct {
type concurrnetMap[K constraints.Ordered, V any] struct {
buckets []Map[K, V]
numOfBuckets uint64
}
func NewConcurrentMap[K constraints.Ordered, V any]() *ConcurrnetMap[K, V] {
func NewConcurrentMap[K constraints.Ordered, V any]() *concurrnetMap[K, V] {
num := defaultNumOfBuckets
buckets := make([]Map[K, V], num)
@ -25,31 +25,31 @@ func NewConcurrentMap[K constraints.Ordered, V any]() *ConcurrnetMap[K, V] {
buckets[i] = NewRWMap[K, V]()
}
return &ConcurrnetMap[K, V]{
return &concurrnetMap[K, V]{
numOfBuckets: uint64(num),
buckets: buckets,
}
}
func (m *ConcurrnetMap[K, V]) Set(key K, value V) {
func (m *concurrnetMap[K, V]) Set(key K, value V) {
m.getBucket(key).Set(key, value)
}
func (m *ConcurrnetMap[K, V]) Get(key K) (V, bool) {
func (m *concurrnetMap[K, V]) Get(key K) (V, bool) {
return m.getBucket(key).Get(key)
}
func (m *ConcurrnetMap[K, V]) Delete(key K) {
func (m *concurrnetMap[K, V]) Delete(key K) {
im := m.getBucket(key)
im.Delete(key)
}
func (m *ConcurrnetMap[K, V]) Exist(key K) bool {
func (m *concurrnetMap[K, V]) Exist(key K) bool {
mm := m.getBucket(key)
return mm.Exist(key)
}
func (m *ConcurrnetMap[K, V]) Iter() <-chan *Entry[K, V] {
func (m *concurrnetMap[K, V]) Iter() <-chan *Entry[K, V] {
num := int(m.numOfBuckets)
ch := make(chan *Entry[K, V], m.Count())
for i := 0; i < num; i++ {
@ -60,7 +60,7 @@ func (m *ConcurrnetMap[K, V]) Iter() <-chan *Entry[K, V] {
return ch
}
func (m *ConcurrnetMap[K, V]) Keys() []K {
func (m *concurrnetMap[K, V]) Keys() []K {
keys := make([]K, m.Count())
for _, b := range m.buckets {
keys = append(keys, b.Keys()...)
@ -69,7 +69,7 @@ func (m *ConcurrnetMap[K, V]) Keys() []K {
return keys
}
func (m *ConcurrnetMap[K, V]) Values() []V {
func (m *concurrnetMap[K, V]) Values() []V {
values := make([]V, 0, m.Count())
for _, v := range m.buckets {
values = append(values, v.Values()...)
@ -78,7 +78,7 @@ func (m *ConcurrnetMap[K, V]) Values() []V {
return values
}
func (m *ConcurrnetMap[K, V]) ToMap() map[K]V {
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())
@ -87,7 +87,7 @@ func (m *ConcurrnetMap[K, V]) ToMap() map[K]V {
return mm
}
func (m *ConcurrnetMap[K, V]) ForEach(f func(K, V)) {
func (m *concurrnetMap[K, V]) ForEach(f func(K, V)) {
var wg sync.WaitGroup
num := int(m.numOfBuckets)
@ -103,7 +103,7 @@ func (m *ConcurrnetMap[K, V]) ForEach(f func(K, V)) {
wg.Wait()
}
func (m *ConcurrnetMap[K, V]) Clone() Map[K, V] {
func (m *concurrnetMap[K, V]) Clone() Map[K, V] {
num := int(m.numOfBuckets)
@ -112,19 +112,19 @@ func (m *ConcurrnetMap[K, V]) Clone() Map[K, V] {
buckets[i] = m.buckets[i].Clone()
}
return &ConcurrnetMap[K, V]{
return &concurrnetMap[K, V]{
buckets: buckets,
numOfBuckets: m.numOfBuckets,
}
}
func (m *ConcurrnetMap[K, V]) Clear() {
func (m *concurrnetMap[K, V]) Clear() {
for i := 0; i < int(m.numOfBuckets); i++ {
m.buckets[i].Clear()
}
}
func (m *ConcurrnetMap[K, V]) Count() int {
func (m *concurrnetMap[K, V]) Count() int {
var count int
for i := 0; i < int(m.numOfBuckets); i++ {
count += m.buckets[i].Count()
@ -133,7 +133,7 @@ func (m *ConcurrnetMap[K, V]) Count() int {
return count
}
func (m *ConcurrnetMap[K, V]) getBucket(k K) Map[K, V] {
func (m *concurrnetMap[K, V]) getBucket(k K) Map[K, V] {
id := getTag(k) % m.numOfBuckets
return m.buckets[id]
}

View File

@ -9,7 +9,12 @@ type hashMap[K constraints.Ordered, V any] struct {
}
func NewHashMap[K constraints.Ordered, V any](maps ...map[K]V) *hashMap[K, V] {
return &hashMap[K, V]{m: make(map[K]V)}
m := make(map[K]V)
if len(maps) > 0 {
m = Merge(maps...)
}
return &hashMap[K, V]{m: m}
}
// synchronized

25
maps/hash_map_test.go Normal file
View File

@ -0,0 +1,25 @@
package maps
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestForEach(t *testing.T) {
m := map[string]any{"b": "b", "a": "a", "d": "d", "c": "c"}
var hashMap = NewHashMap(map[string]any{"b": "b", "a": "a", "d": "d", "c": "c"})
assert.True(t, hashMap.Exist("a"))
assert.Equal(t, len(m), hashMap.Count())
hashMap.ForEach(func(s string, a any) {
if _, ok := m[s]; !ok {
t.Fatal("值不存在")
}
})
for k := range m {
assert.True(t, hashMap.Exist(k))
}
}

15
maps/option.go Normal file
View File

@ -0,0 +1,15 @@
package maps
import (
"sync"
"github.com/charlienet/go-mixed/locker"
)
type options struct {
mu sync.Locker
}
func acquireDefaultOptions() *options {
return &options{mu: locker.NewEmptyLocker()}
}

View File

@ -36,8 +36,8 @@ func (m *rw_map[K, V]) Get(key K) (V, bool) {
}
func (m *rw_map[K, V]) Delete(key K) {
m.mu.RLock()
defer m.mu.RUnlock()
m.mu.Lock()
defer m.mu.Unlock()
m.m.Delete(key)
}

View File

@ -5,6 +5,8 @@ import (
"golang.org/x/exp/constraints"
"golang.org/x/exp/slices"
xmaps "golang.org/x/exp/maps"
)
var (
@ -26,7 +28,7 @@ type sorted_map[K constraints.Ordered, V any] struct {
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),
keys: xmaps.Keys(merged),
maps: NewHashMap(merged),
}
}
@ -115,12 +117,6 @@ 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]", Join[K, V](m, " ", func(k K, v V) string {
return fmt.Sprintf("%v:%v", k, v)
}))
}
func (m *sorted_map[K, V]) Asc() SortedMap[K, V] {
keys := m.keys
slices.Sort(keys)
@ -144,11 +140,8 @@ func (m *sorted_map[K, V]) Desc() SortedMap[K, 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
func (m *sorted_map[K, V]) String() string {
return fmt.Sprintf("map[%s]", Join[K, V](m, " ", func(k K, v V) string {
return fmt.Sprintf("%v:%v", k, v)
}))
}

View File

@ -3,6 +3,8 @@ package maps
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSortMapConvert(t *testing.T) {
@ -16,9 +18,17 @@ func TestSortMapConvert(t *testing.T) {
}
func TestSortedJoin(t *testing.T) {
var m = NewSortedMap(map[string]any{"b": "b", "a": "a", "d": "d", "c": "c"}).Asc()
m := NewSortedMap(map[string]any{"b": "b", "a": "a", "d": "d", "c": "c"}).Asc()
t.Log(Join[string, any](m, "&", func(k string, v any) string {
f := func(k string, v any) string {
return fmt.Sprintf("%s=%v", k, v)
}))
}
ret := Join[string, any](m, "&", f)
assert.Equal(t, ret, "a=a&b=b&c=c&d=d")
ret = Join[string, any](m.Desc(), "&", f)
assert.Equal(t, "d=d&c=c&b=b&a=a", ret)
}