Skip to content

Commit c22f46d

Browse files
authored
Merge pull request #7 from lxzan/dev
fix tree map
2 parents e1f674d + 09e5354 commit c22f46d

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

internal/treemap/treemap.go

+34-21
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,77 @@ import (
55
)
66

77
func New[T any](sep string) *TreeMap[T] {
8-
return &TreeMap[T]{sep: sep, children: make(map[string]*TreeMap[T])}
8+
return &TreeMap[T]{
9+
sep: sep,
10+
root: &Element[T]{children: make(map[string]*Element[T])},
11+
}
912
}
1013

11-
type TreeMap[T any] struct {
12-
children map[string]*TreeMap[T]
13-
sep string
14-
key string
15-
value T
16-
}
14+
type (
15+
TreeMap[T any] struct {
16+
sep string
17+
root *Element[T]
18+
}
1719

18-
func (c *TreeMap[T]) Put(key string, val T) {
19-
if !strings.Contains(key, c.sep) {
20-
c.children[key] = &TreeMap[T]{key: key, value: val}
21-
} else {
22-
c.doPut(c, &TreeMap[T]{key: key, value: val}, key)
20+
Element[T any] struct {
21+
ok bool
22+
children map[string]*Element[T]
23+
key string
24+
value T
2325
}
26+
)
27+
28+
func (c *TreeMap[T]) Put(key string, val T) {
29+
node := &Element[T]{key: key, value: val, ok: true}
30+
c.doPut(c.root, node, key)
2431
}
2532

26-
func (c *TreeMap[T]) doPut(far, son *TreeMap[T], key string) {
33+
func (c *TreeMap[T]) doPut(far, son *Element[T], key string) {
2734
if far.children == nil {
28-
far.children = make(map[string]*TreeMap[T])
35+
far.children = make(map[string]*Element[T])
2936
}
3037

3138
index := strings.Index(key, c.sep)
3239
if index < 0 {
33-
far.children[key] = son
40+
if node := far.children[key]; node == nil {
41+
far.children[key] = son
42+
} else {
43+
node.value, node.ok = son.value, son.ok
44+
}
3445
return
3546
}
3647

3748
s0, s1 := key[:index], key[index+1:]
3849
next := far.children[s0]
3950
if far.children[s0] == nil {
40-
next = &TreeMap[T]{}
51+
next = &Element[T]{}
4152
far.children[s0] = next
4253
}
4354
c.doPut(next, son, s1)
4455
}
4556

4657
func (c *TreeMap[T]) Get(key string) (v T, exist bool) {
47-
if result, ok := c.children[key]; ok {
58+
if result, ok := c.root.children[key]; ok && result.ok {
4859
v, exist = result.value, true
4960
}
5061
return
5162
}
5263

5364
func (c *TreeMap[T]) Match(key string, cb func(k string, v T)) {
54-
c.doMatch(c, key, cb)
65+
c.doMatch(c.root, key, cb)
5566
}
5667

57-
func (c *TreeMap[T]) doMatch(cur *TreeMap[T], key string, cb func(string, T)) {
68+
func (c *TreeMap[T]) doMatch(cur *Element[T], key string, cb func(string, T)) {
5869
index := strings.Index(key, c.sep)
5970
if index < 0 {
6071
if key == "*" {
6172
for _, node := range cur.children {
62-
cb(node.key, node.value)
73+
if node.ok {
74+
cb(node.key, node.value)
75+
}
6376
}
6477
} else {
65-
if result, ok := cur.children[key]; ok {
78+
if result, ok := cur.children[key]; ok && result.ok {
6679
cb(result.key, result.value)
6780
}
6881
}

internal/treemap/treemap_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/lxzan/event_emitter/internal/helper"
66
"github.com/stretchr/testify/assert"
77
"strings"
8+
"sync"
89
"testing"
910
)
1011

@@ -81,3 +82,26 @@ func TestTreeMap_Get(t *testing.T) {
8182
_, ok := tm.Get("~aha")
8283
assert.False(t, ok)
8384
}
85+
86+
func TestTreeMap_Match(t *testing.T) {
87+
var tm = New[uint8](".")
88+
tm.Put("api.v1.actions.eat", 1)
89+
tm.Put("api.v1.actions", 2)
90+
var wg = new(sync.WaitGroup)
91+
wg.Add(2)
92+
var sum = uint8(0)
93+
tm.Match("api.v1.*.eat", func(k string, v uint8) {
94+
sum += v
95+
wg.Done()
96+
})
97+
tm.Match("api.v1.*", func(k string, v uint8) {
98+
sum += v
99+
wg.Done()
100+
})
101+
tm.Match("api.v1.any", func(k string, v uint8) {
102+
sum += v
103+
wg.Done()
104+
})
105+
wg.Wait()
106+
assert.Equal(t, sum, uint8(3))
107+
}

0 commit comments

Comments
 (0)