Skip to content

Commit ace2b96

Browse files
authored
Merge pull request #3 from antlabs/rwmap
Rwmap
2 parents 6d29579 + c7cdb97 commit ace2b96

File tree

8 files changed

+392
-0
lines changed

8 files changed

+392
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: "\U0001F91D Bug Report"
3+
about: As a User, I want to report a Bug.
4+
labels: type/bug
5+
---
6+
7+
## Bug Report
8+
9+
Please answer these questions before submitting your issue. Thanks!
10+
11+
### 1. Minimal reproduce step (Required)
12+
13+
<!-- a step by step guide for reproducing the bug. -->
14+
15+
### 2. What did you expect to see? (Required)
16+
17+
### 3. What did you see instead (Required)
18+
19+
### 4. What is your gstl version? (Required)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: "\U0001F44F Feature Request"
3+
about: As a user, I want to request a New Feature on the product.
4+
labels: type/feature-request
5+
---
6+
7+
## Feature Request
8+
9+
**Is your feature request related to a problem? Please describe:**
10+
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
11+
12+
**Describe the feature you'd like:**
13+
<!-- A clear and concise description of what you want to happen. -->
14+
15+
**Describe alternatives you've considered:**
16+
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
17+
18+
**Teachability, Documentation, Adoption, Migration Strategy:**
19+
<!-- If you can, explain some scenarios how users might use this, situations it would be helpful in. Any API designs, mockups, or diagrams are also helpful. -->
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: "\U0001F600 Ask a Question"
3+
about: I want to ask a question.
4+
labels: type/question
5+
---
6+
7+
## General Question
8+
9+
<!--
10+
11+
Before asking a question, make sure you have:
12+
13+
- Searched existing Stack Overflow questions.
14+
- Googled your question.
15+
- Searched open and closed [GitHub issues](https://github.com/antlabs/gstl/issues)
16+
- Read the documentation:
17+
- [gstl Readme](https://github.com/antlabs/gstl/blob/master/README.md)
18+
19+
-->

.github/workflows/go.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Go
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
9+
build:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
go: ['1.19']
14+
name: Go ${{ matrix.go }} sample
15+
16+
steps:
17+
18+
- name: Set up Go 1.19
19+
uses: actions/setup-go@v1
20+
with:
21+
go-version: ${{ matrix.go }}
22+
id: go
23+
24+
- name: Check out code into the Go module directory
25+
uses: actions/checkout@v1
26+
27+
- name: Get dependencies
28+
run: |
29+
go get -v -t -d ./...
30+
if [ -f Gopkg.toml ]; then
31+
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
32+
dep ensure
33+
fi
34+
35+
- name: Test
36+
run: go test -v -coverprofile='coverage.out' -covermode=count ./...
37+
38+
- name: Upload Coverage report
39+
uses: codecov/codecov-action@v1
40+
with:
41+
token: ${{secrets.CODECOV_TOKEN}}
42+
file: ./coverage.out

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313

1414
# Dependency directories (remove the comment below to include it)
1515
# vendor/
16+
cover.cov

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,28 @@ m["b"] = "2"
152152
m["c"] = "3"
153153
get := mapex.Values(m)
154154
```
155+
## 十一、`rwmap`
156+
rwmap与sync.Map类似支持并发访问,只解决sync.Map 2个问题.
157+
1. 没有Len成员函数
158+
2. 以及没有使用泛型语法,有运行才发现类型使用错误的烦恼
159+
```go
160+
var m RWMap[string, string] // 声明一个string, string的map
161+
m.Store("hello", "1") // 保存
162+
v1, ok1 := m.Load("hello") // 获取值
163+
v1, ok1 = m.LoadAndDelete("hello") //返回hello对应值,然后删除hello
164+
Delete("hello") // 删除
165+
v1, ok1 = m.LoadOrStore("hello", "world")
166+
167+
// 遍历,使用回调函数
168+
m.Range(func(key, val string) bool {
169+
fmt.Printf("k:%s, val:%s\n"i, key, val)
170+
return true
171+
})
172+
173+
// 遍历,迭代器
174+
for pair := range m.Iter() {
175+
fmt.Printf("k:%s, val:%s\n", pair.Key, pair.Val)
176+
}
177+
178+
m.Len()// 获取长度
179+
```

rwmap/rwmap.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// apache 2.0 antlabs
2+
3+
package rwmap
4+
5+
import "sync"
6+
7+
type RWMap[K comparable, V any] struct {
8+
rw sync.RWMutex
9+
m map[K]V
10+
}
11+
12+
type Pair[K comparable, V any] struct {
13+
Key K
14+
Val V
15+
}
16+
17+
// 通过new函数分配可以指定map的长度
18+
func New[K comparable, V any](l int) *RWMap[K, V] {
19+
return &RWMap[K, V]{
20+
m: make(map[K]V, l),
21+
}
22+
}
23+
24+
// 删除
25+
func (r *RWMap[K, V]) Delete(key K) {
26+
r.rw.Lock()
27+
delete(r.m, key)
28+
r.rw.Unlock()
29+
}
30+
31+
// 加载
32+
func (r *RWMap[K, V]) Load(key K) (value V, ok bool) {
33+
r.rw.RLock()
34+
value, ok = r.m[key]
35+
r.rw.RUnlock()
36+
return
37+
38+
}
39+
40+
// 获取值,然后并删除
41+
func (r *RWMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) {
42+
r.rw.Lock()
43+
if r.m == nil {
44+
r.rw.Unlock()
45+
return
46+
}
47+
value, loaded = r.m[key]
48+
delete(r.m, key)
49+
r.rw.Unlock()
50+
return
51+
}
52+
53+
// 存在返回现有的值,loaded 为true
54+
// 不存在就保存现在的值,loaded为false
55+
func (r *RWMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) {
56+
r.rw.Lock()
57+
if r.m == nil {
58+
r.m = make(map[K]V)
59+
}
60+
actual, loaded = r.m[key]
61+
if !loaded {
62+
actual = value
63+
r.m[key] = actual
64+
}
65+
r.rw.Unlock()
66+
return
67+
}
68+
69+
func (r *RWMap[K, V]) Range(f func(key K, value V) bool) {
70+
r.rw.RLock()
71+
for k, v := range r.m {
72+
if !f(k, v) {
73+
break
74+
}
75+
}
76+
r.rw.RUnlock()
77+
}
78+
79+
func (r *RWMap[K, V]) Iter() <-chan Pair[K, V] {
80+
p := make(chan Pair[K, V])
81+
go func() {
82+
r.rw.RLock()
83+
for k, v := range r.m {
84+
p <- Pair[K, V]{Key: k, Val: v}
85+
}
86+
close(p)
87+
r.rw.RUnlock()
88+
89+
}()
90+
return p
91+
}
92+
93+
// 保存值
94+
func (r *RWMap[K, V]) Store(key K, value V) {
95+
r.rw.Lock()
96+
if r.m == nil {
97+
r.m = make(map[K]V)
98+
}
99+
r.m[key] = value
100+
r.rw.Unlock()
101+
}
102+
103+
// 返回长度
104+
func (r *RWMap[K, V]) Len() (l int) {
105+
r.rw.RLock()
106+
l = len(r.m)
107+
r.rw.RUnlock()
108+
return
109+
}

0 commit comments

Comments
 (0)