Skip to content

Commit

Permalink
新增mapi.Len()方法 (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
wureny authored Jan 9, 2024
1 parent 5056d18 commit eba89e1
Show file tree
Hide file tree
Showing 11 changed files with 281 additions and 0 deletions.
4 changes: 4 additions & 0 deletions mapx/builtin_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ func newBuiltinMap[K comparable, V any](capacity int) *builtinMap[K, V] {
data: make(map[K]V, capacity),
}
}

func (b *builtinMap[K, V]) Len() int64 {
return int64(len(b.data))
}
36 changes: 36 additions & 0 deletions mapx/builtin_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,42 @@ func TestBuiltinMap_Values(t *testing.T) {
}
}

func TestBuiltinMap_Len(t *testing.T) {
testCases := []struct {
name string
data map[string]string

wantLen int64
}{
{
name: "got len",
data: map[string]string{
"key1": "val1",
"key2": "val2",
"key3": "val3",
"key4": "val4",
},
wantLen: 4,
},
{
name: "empty map",
data: map[string]string{},
wantLen: 0,
},
{
name: "nil map",
wantLen: 0,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
m := builtinMapOf[string, string](tc.data)
assert.Equal(t, tc.wantLen, m.Len())
})
}
}

func builtinMapOf[K comparable, V any](data map[K]V) *builtinMap[K, V] {
return &builtinMap[K, V]{data: data}
}
4 changes: 4 additions & 0 deletions mapx/hashmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,7 @@ func (n *node[T, ValType]) formatting() {
n.value = val
n.next = nil
}

func (m *HashMap[T, ValType]) Len() int64 {
return int64(len(m.hashmap))
}
71 changes: 71 additions & 0 deletions mapx/hashmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,77 @@ func TestHashMap_Keys_Values(t *testing.T) {
}
}

func TestHashMap_Len(t *testing.T) {
testCases := []struct {
name string
genHashMap func() *HashMap[testData, int]
wantLen int64
}{
{
name: "empty",
genHashMap: func() *HashMap[testData, int] {
return NewHashMap[testData, int](10)
},
wantLen: 0,
},
{
name: "single key",
genHashMap: func() *HashMap[testData, int] {
testHashMap := NewHashMap[testData, int](10)
err := testHashMap.Put(newTestData(1), 1)
require.NoError(t, err)
return testHashMap
},
wantLen: 1,
},
{
name: "multiple keys",
genHashMap: func() *HashMap[testData, int] {
testHashMap := NewHashMap[testData, int](10)
for _, val := range []int{1, 2} {
err := testHashMap.Put(newTestData(val), val)
require.NoError(t, err)
}
return testHashMap
},
wantLen: 2,
},
{
name: "same key",
genHashMap: func() *HashMap[testData, int] {
testHashMap := NewHashMap[testData, int](10)
err := testHashMap.Put(newTestData(1), 1)
require.NoError(t, err)
// 验证id相同,覆盖的场景
err = testHashMap.Put(newTestData(1), 11)
require.NoError(t, err)
return testHashMap
},
wantLen: 1,
},
{
name: "multi with same key",
genHashMap: func() *HashMap[testData, int] {
testHashMap := NewHashMap[testData, int](10)
for _, val := range []int{1, 2} {
// val为1、2
err := testHashMap.Put(newTestData(val), val*10)
require.NoError(t, err)
}
err := testHashMap.Put(newTestData(1), 11)
require.NoError(t, err)
return testHashMap
},
wantLen: 2,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.wantLen, tc.genHashMap().Len())
})
}
}

type testData struct {
id int
}
Expand Down
4 changes: 4 additions & 0 deletions mapx/linkedmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,7 @@ func (l *LinkedMap[K, V]) Values() []V {
}
return values
}

func (l *LinkedMap[K, V]) Len() int64 {
return int64(l.length)
}
36 changes: 36 additions & 0 deletions mapx/linkedmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,39 @@ func TestLinkedMap_PutAndDelete(t *testing.T) {
})
}
}

func TestLinkedMap_Len(t *testing.T) {
testCases := []struct {
name string
linkedMap func(t *testing.T) *LinkedMap[int, int]

wantLen int64
}{
{
name: "empty linked map",
linkedMap: func(t *testing.T) *LinkedMap[int, int] {
linkedTreeMap, _ := NewLinkedTreeMap[int, int](ekit.ComparatorRealNumber[int])
return linkedTreeMap
},

wantLen: 0,
},
{
name: "not empty linked map",
linkedMap: func(t *testing.T) *LinkedMap[int, int] {
linkedTreeMap, _ := NewLinkedTreeMap[int, int](ekit.ComparatorRealNumber[int])
assert.NoError(t, linkedTreeMap.Put(1, 1))
assert.NoError(t, linkedTreeMap.Put(2, 2))
assert.NoError(t, linkedTreeMap.Put(3, 3))
return linkedTreeMap
},

wantLen: 3,
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.wantLen, tt.linkedMap(t).Len())
})
}
}
5 changes: 5 additions & 0 deletions mapx/multi_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,8 @@ func (m *MultiMap[K, V]) Values() [][]V {
}
return copyValues
}

// Len 返回 MultiMap 键值对的数量
func (m *MultiMap[K, V]) Len() int64 {
return m.m.Len()
}
78 changes: 78 additions & 0 deletions mapx/multi_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,3 +594,81 @@ func TestMultiMap_PutMany(t *testing.T) {
})
}
}

func TestMultiMap_Len(t *testing.T) {
testCases := []struct {
name string
multiTreeMap *MultiMap[int, int]
multiHashMap *MultiMap[testData, int]
wantLen int64
}{
{
name: "empty",
multiTreeMap: getMultiTreeMap(),
multiHashMap: getMultiHashMap(),

wantLen: 0,
},
{
name: "single",
multiTreeMap: func() *MultiMap[int, int] {
multiTreeMap := getMultiTreeMap()
_ = multiTreeMap.Put(1, 1)
return multiTreeMap
}(),
multiHashMap: func() *MultiMap[testData, int] {
multiHashMap := getMultiHashMap()
_ = multiHashMap.Put(testData{id: 1}, 1)
return multiHashMap
}(),

wantLen: 1,
},
{
name: "multiple",
multiTreeMap: func() *MultiMap[int, int] {
multiTreeMap := getMultiTreeMap()
_ = multiTreeMap.Put(1, 1)
_ = multiTreeMap.Put(2, 2)
_ = multiTreeMap.Put(3, 3)
return multiTreeMap
}(),
multiHashMap: func() *MultiMap[testData, int] {
multiHashMap := getMultiHashMap()
_ = multiHashMap.Put(testData{id: 1}, 1)
_ = multiHashMap.Put(testData{id: 2}, 2)
_ = multiHashMap.Put(testData{id: 3}, 3)
return multiHashMap
}(),

wantLen: 3,
},
{
name: "multiple with same key",
multiTreeMap: func() *MultiMap[int, int] {
multiTreeMap := getMultiTreeMap()
_ = multiTreeMap.Put(1, 1)
_ = multiTreeMap.Put(1, 2)
_ = multiTreeMap.Put(1, 3)
return multiTreeMap
}(),
multiHashMap: func() *MultiMap[testData, int] {
multiHashMap := getMultiHashMap()
_ = multiHashMap.Put(testData{id: 1}, 1)
_ = multiHashMap.Put(testData{id: 1}, 2)
_ = multiHashMap.Put(testData{id: 1}, 3)
return multiHashMap
}(),
wantLen: 1,
},
}
for _, tt := range testCases {
t.Run("MultiTreeMap", func(t *testing.T) {
assert.Equal(t, tt.wantLen, tt.multiTreeMap.Len())
})

t.Run("MultiHashMap", func(t *testing.T) {
assert.Equal(t, tt.wantLen, tt.multiHashMap.Len())
})
}
}
5 changes: 5 additions & 0 deletions mapx/treemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@ func (treeMap *TreeMap[T, V]) Values() []V {
return vals
}

// Len 返回了键值对的数量
func (treeMap *TreeMap[T, V]) Len() int64 {
return int64(treeMap.tree.Size())
}

var _ mapi[any, any] = (*TreeMap[any, any])(nil)
36 changes: 36 additions & 0 deletions mapx/treemap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,42 @@ func TestTreeMap_Delete(t *testing.T) {
}
}

func TestTreeMap_Len(t *testing.T) {
var tests = []struct {
name string
m map[int]int
len int64
}{
{
name: "empty-TreeMap",
m: map[int]int{},
len: 0,
},
{
name: "find",
m: map[int]int{
1: 1,
2: 2,
0: 0,
3: 3,
5: 5,
4: 4,
},
len: 6,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
treeMap, _ := NewTreeMap[int, int](compare())
for k, v := range tt.m {
err := treeMap.Put(k, v)
require.NoError(t, err)
}
assert.Equal(t, tt.len, treeMap.Len())
})
}
}

func compare() ekit.Comparator[int] {
return ekit.ComparatorRealNumber[int]
}
Expand Down
2 changes: 2 additions & 0 deletions mapx/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ type mapi[K any, V any] interface {
// 注意,当你调用多次拿到的结果不一定相等
// 取决于具体实现
Values() []V
// 返回键值对数量
Len() int64
}

0 comments on commit eba89e1

Please sign in to comment.