Skip to content

Commit d7240dc

Browse files
committed
support go 1.18
1 parent f9aed52 commit d7240dc

File tree

4 files changed

+29
-25
lines changed

4 files changed

+29
-25
lines changed

README.md

+12-9
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,13 @@ See all the details: [link](https://github.com/CppCon/CppCon2015/blob/master/Pre
7878

7979
# How
8080

81+
After go 1.18
8182
```bash
82-
go get github.com/csimplestring/go-left-right
83+
go get github.com/csimplestring/[email protected]
84+
```
85+
Before go 1.18
86+
```bash
87+
go get github.com/csimplestring/[email protected]
8388
```
8489

8590
Then you can use it to wrap any data structures. See the below example.
@@ -89,7 +94,7 @@ Then you can use it to wrap any data structures. See the below example.
8994
import github.com/csimplestring/go-left-right/primitive
9095

9196
type LRMap struct {
92-
*primitive.LeftRightPrimitive
97+
*primitive.LeftRightPrimitive[map[int]int]
9398

9499
// you have to provides 2 identical instances
95100
left map[int]int
@@ -103,26 +108,24 @@ func newIntMap() *LRMap {
103108
right: make(map[int]int),
104109
}
105110

106-
m.LeftRightPrimitive = primitive.New()
111+
m.LeftRightPrimitive = primitive.New[map[int]int]()
107112

108113
return m
109114
}
110115

111116
func (lr *LRMap) Get(k int) (val int, exist bool) {
112117

113118
// Go does not have generics, so have to use interface{} for lambda's arguments
114-
lr.ApplyReadFn(lr.left, lr.right, func(instance interface{}) {
115-
m := instance.(map[int]int)
116-
val, exist = m[k]
119+
lr.ApplyReadFn(lr.left, lr.right, func(instance map[int]int) {
120+
val, exist = instance[k]
117121
})
118122

119123
return
120124
}
121125

122126
func (lr *LRMap) Put(key, val int) {
123-
lr.ApplyWriteFn(lr.left, lr.right, func(instance interface{}) {
124-
m := instance.(map[int]int)
125-
m[key] = val
127+
lr.ApplyWriteFn(lr.left, lr.right, func(instance map[int]int) {
128+
instance[key] = val
126129
})
127130
}
128131
```

go.mod

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module github.com/csimplestring/go-left-right
22

3-
go 1.15
3+
go 1.18
44

55
require github.com/linxGnu/go-adder v0.2.0
6+
7+
require github.com/valyala/fastrand v1.0.0 // indirect

map.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import "github.com/csimplestring/go-left-right/primitive"
44

55
// LRMap utilises the left-right pattern to handle concurrent read-write.
66
type LRMap struct {
7-
*primitive.LeftRightPrimitive
7+
*primitive.LeftRightPrimitive[map[int]int]
88

99
left map[int]int
1010
right map[int]int
@@ -17,24 +17,23 @@ func newIntMap() *LRMap {
1717
right: make(map[int]int),
1818
}
1919

20-
m.LeftRightPrimitive = primitive.New()
20+
m.LeftRightPrimitive = primitive.New[map[int]int]()
2121

2222
return m
2323
}
2424

2525
func (lr *LRMap) Get(k int) (val int, exist bool) {
2626

27-
lr.ApplyReadFn(lr.left, lr.right, func(instance interface{}) {
28-
m := instance.(map[int]int)
29-
val, exist = m[k]
27+
lr.ApplyReadFn(lr.left, lr.right, func(instance map[int]int) {
28+
val, exist = instance[k]
3029
})
3130

3231
return
3332
}
3433

3534
func (lr *LRMap) Put(key, val int) {
36-
lr.ApplyWriteFn(lr.left, lr.right, func(instance interface{}) {
37-
m := instance.(map[int]int)
35+
lr.ApplyWriteFn(lr.left, lr.right, func(instance map[int]int) {
36+
m := instance
3837
m[key] = val
3938
})
4039
}

primitive/primitive.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const ReadOnLeft int32 = -1
99
const ReadOnRight int32 = 1
1010

1111
// LeftRightPrimitive provides the basic core of the leftt-right pattern.
12-
type LeftRightPrimitive struct {
12+
type LeftRightPrimitive[T any] struct {
1313
// readIndicators is an array of 2 read-indicators, counting the reader numbers on the left/right instance
1414
readIndicators [2]ReadIndicator
1515
// versionIndex is the index for readIndicators, 0 means reading on left, 1 means reading on right
@@ -19,9 +19,9 @@ type LeftRightPrimitive struct {
1919
}
2020

2121
// New creates a LeftRightPrimitive
22-
func New() *LeftRightPrimitive {
22+
func New[T any]() *LeftRightPrimitive[T] {
2323

24-
m := &LeftRightPrimitive{
24+
m := &LeftRightPrimitive[T]{
2525
readIndicators: [2]ReadIndicator{
2626
newDistributedAtomicReadIndicator(),
2727
newDistributedAtomicReadIndicator(),
@@ -37,19 +37,19 @@ func New() *LeftRightPrimitive {
3737
}
3838

3939
// readerArrive shall be called by the reader goroutine before start reading
40-
func (lr *LeftRightPrimitive) readerArrive() int {
40+
func (lr *LeftRightPrimitive[T]) readerArrive() int {
4141
idx := atomic.LoadInt32(lr.versionIndex)
4242
lr.readIndicators[idx].arrive()
4343
return int(idx)
4444
}
4545

4646
// readerDepart shall be called by the reader goroutine after finish reading
47-
func (lr *LeftRightPrimitive) readerDepart(localVI int) {
47+
func (lr *LeftRightPrimitive[T]) readerDepart(localVI int) {
4848
lr.readIndicators[localVI].depart()
4949
}
5050

5151
// writerToggleVersionAndWait shall be called by a single writer goroutine when applying the modification
52-
func (lr *LeftRightPrimitive) writerToggleVersionAndWait() {
52+
func (lr *LeftRightPrimitive[T]) writerToggleVersionAndWait() {
5353

5454
localVI := atomic.LoadInt32(lr.versionIndex)
5555
prevVI := int(localVI % 2)
@@ -70,7 +70,7 @@ func (lr *LeftRightPrimitive) writerToggleVersionAndWait() {
7070
}
7171

7272
// ApplyReadFn applies read operation on the chosen instance, oh, I really need generics, interface type is ugly
73-
func (lr *LeftRightPrimitive) ApplyReadFn(l interface{}, r interface{}, fn func(interface{})) {
73+
func (lr *LeftRightPrimitive[T]) ApplyReadFn(l T, r T, fn func(T)) {
7474

7575
lvi := lr.readerArrive()
7676

@@ -87,7 +87,7 @@ func (lr *LeftRightPrimitive) ApplyReadFn(l interface{}, r interface{}, fn func(
8787

8888
// ApplyWriteFn applies write operation on the chosen instance, write operation is done twice, on the left and right
8989
// instance respectively, this might make writing longer, but the readers are wait-free.
90-
func (lr *LeftRightPrimitive) ApplyWriteFn(l interface{}, r interface{}, fn func(interface{})) {
90+
func (lr *LeftRightPrimitive[T]) ApplyWriteFn(l T, r T, fn func(T)) {
9191

9292
side := atomic.LoadInt32(lr.sideToRead)
9393
if side == ReadOnLeft {

0 commit comments

Comments
 (0)