@@ -3,26 +3,27 @@ package gache
3
3
import (
4
4
"sync"
5
5
"sync/atomic"
6
+ "unsafe"
6
7
)
7
8
8
- type Map [K , V comparable ] struct {
9
+ type Map [K comparable , V any ] struct {
9
10
mu sync.Mutex
10
11
read atomic.Pointer [readOnly [K , V ]]
11
12
dirty map [K ]* entry [V ]
12
13
misses int
13
14
}
14
15
15
- type readOnly [K , V comparable ] struct {
16
+ type readOnly [K comparable , V any ] struct {
16
17
m map [K ]* entry [V ]
17
18
amended bool
18
19
}
19
20
20
- type entry [V comparable ] struct {
21
+ type entry [V any ] struct {
21
22
expunged atomic.Pointer [V ]
22
23
p atomic.Pointer [V ]
23
24
}
24
25
25
- func newEntry [V comparable ](v V ) (e * entry [V ]) {
26
+ func newEntry [V any ](v V ) (e * entry [V ]) {
26
27
e = & entry [V ]{}
27
28
e .expunged .Store (new (V ))
28
29
e .p .Store (& v )
@@ -46,7 +47,6 @@ func (m *Map[K, V]) Load(key K) (value V, ok bool) {
46
47
e , ok = read .m [key ]
47
48
if ! ok && read .amended {
48
49
e , ok = m .dirty [key ]
49
-
50
50
m .missLocked ()
51
51
}
52
52
m .mu .Unlock ()
@@ -71,7 +71,7 @@ func (m *Map[K, V]) Store(key K, value V) {
71
71
72
72
func (e * entry [V ]) tryCompareAndSwap (old , new V ) (ok bool ) {
73
73
p := e .p .Load ()
74
- if p == nil || p == e .expunged .Load () || * p != old {
74
+ if p == nil || p == e .expunged .Load () || unsafe . Pointer ( p ) != unsafe . Pointer ( & old ) {
75
75
return false
76
76
}
77
77
@@ -81,7 +81,7 @@ func (e *entry[V]) tryCompareAndSwap(old, new V) (ok bool) {
81
81
return true
82
82
}
83
83
p = e .p .Load ()
84
- if p == nil || p == e .expunged .Load () || * p != old {
84
+ if p == nil || p == e .expunged .Load () || unsafe . Pointer ( p ) != unsafe . Pointer ( & old ) {
85
85
return false
86
86
}
87
87
}
@@ -116,7 +116,6 @@ func (m *Map[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) {
116
116
m .missLocked ()
117
117
} else {
118
118
if ! read .amended {
119
-
120
119
m .dirtyLocked ()
121
120
m .read .Store (& readOnly [K , V ]{m : read .m , amended : true })
122
121
}
@@ -253,7 +252,6 @@ func (m *Map[K, V]) CompareAndSwap(key K, old, new V) (swapped bool) {
253
252
swapped = e .tryCompareAndSwap (old , new )
254
253
} else if e , ok := m .dirty [key ]; ok {
255
254
swapped = e .tryCompareAndSwap (old , new )
256
-
257
255
m .missLocked ()
258
256
}
259
257
return swapped
@@ -268,14 +266,13 @@ func (m *Map[K, V]) CompareAndDelete(key K, old V) (deleted bool) {
268
266
e , ok = read .m [key ]
269
267
if ! ok && read .amended {
270
268
e , ok = m .dirty [key ]
271
-
272
269
m .missLocked ()
273
270
}
274
271
m .mu .Unlock ()
275
272
}
276
273
for ok {
277
274
p := e .p .Load ()
278
- if p == nil || p == e .expunged .Load () || * p != old {
275
+ if p == nil || p == e .expunged .Load () || unsafe . Pointer ( p ) != unsafe . Pointer ( & old ) {
279
276
return false
280
277
}
281
278
if e .p .CompareAndSwap (p , nil ) {
@@ -286,7 +283,6 @@ func (m *Map[K, V]) CompareAndDelete(key K, old V) (deleted bool) {
286
283
}
287
284
288
285
func (m * Map [K , V ]) Range (f func (key K , value V ) bool ) {
289
-
290
286
read := m .loadReadOnly ()
291
287
if read .amended {
292
288
0 commit comments