-
Notifications
You must be signed in to change notification settings - Fork 12
/
cache.go
196 lines (167 loc) · 5.29 KB
/
cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Copyright [2020-2023] [guonaihong]
package pcopy
import (
"reflect"
"sync"
"unsafe"
)
type (
newBaseTypeFunc func(interface{}) interface{}
setUnsafeFunc func(dstAddr, srcAddr unsafe.Pointer)
setReflectFunc func(dstType, srcType reflect.Type, dst, src unsafe.Pointer, opt options, of *offsetAndFunc) error
// setReflectFunc func(dstType, srcType reflect.Type, dstValType, srcValType reflect.Type, dst, src unsafe.Pointer, opt options) error
setUnsafeFuncTab map[reflect.Kind]setUnsafeFunc
setReflectFuncTab map[reflect.Kind]setReflectFunc
setBaseMapFuncTab map[baseMapKind]setUnsafeFunc
)
type baseMapKind struct {
key reflect.Kind
val reflect.Kind
}
type baseTypeTmpl struct {
TypeName []string
}
var cacheAllFunc sync.Map
type dstSrcType struct {
dst reflect.Type
src reflect.Type
}
type allFieldFunc struct {
fieldFuncs []offsetAndFunc
}
type flag int
const (
// 空值类型
emptyTypeSet flag = iota
baseTypeSet // 基础类型
sliceTypeSet // slice类型
baseSliceTypeSet // 基础类型的slice
structTypeSet // 结构体类型
baseMapTypeSet // 基础类型的map
debugTypeSet // debug类型
)
type offsetAndFunc struct {
dstType reflect.Type
srcType reflect.Type
dstOffset int
srcOffset int
unsafeSet setUnsafeFunc
reflectSet setReflectFunc
// 找到一个复合类型
nextComposite *allFieldFunc
createFlag flag // 记录offsetAndFunc这个对象生成的触发点, debug时用
}
func saveToCache(a dstSrcType, fieldFunc *allFieldFunc) {
// fmt.Printf("saveToCache: dst = %v, src = %v\n", a.dst, a.src)
cacheAllFunc.LoadOrStore(a, fieldFunc)
}
func hasSetFromCache(a dstSrcType) (exist bool) {
_, ok := cacheAllFunc.Load(a)
return ok
}
func getFromCacheSetAndRun(a dstSrcType, dstAddr, srcAddr unsafe.Pointer, opt options) (exist bool, err error) {
v, ok := cacheAllFunc.Load(a)
if !ok {
return false, nil
}
err = v.(*allFieldFunc).do(dstAddr, srcAddr, opt)
// cacheFunc.do(dstAddr, srcAddr)
return true, err
}
func newAllFieldFunc() (rv *allFieldFunc) {
rv = &allFieldFunc{fieldFuncs: make([]offsetAndFunc, 0, 5)}
return
}
func (af *allFieldFunc) append(fieldFunc offsetAndFunc) {
af.fieldFuncs = append(af.fieldFuncs, fieldFunc)
}
func (c *allFieldFunc) do(dstBaseAddr, srcBaseAddr unsafe.Pointer, opt options) (err error) {
for _, v := range c.fieldFuncs {
var kind reflect.Kind
if v.unsafeSet == nil && v.reflectSet == nil {
goto next
}
kind = v.srcType.Kind()
switch {
// dst如果是ptr
// 修改这里的代码,也要修改pcopy()函数里面的代码
// 这里必须要放在第一
case v.dstType.Kind() == reflect.Ptr:
if err := v.reflectSet(v.dstType, v.srcType, add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset), opt, &v); err != nil {
return err
}
// 这里必须放在第二
case kind == reflect.Ptr:
if err := v.reflectSet(v.dstType, v.srcType, add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset), opt, &v); err != nil {
return err
}
// 特殊类型的struct才会进这里, 正常情况一个struct对应一个allFieldFunc
case v.dstType.Kind() == reflect.Struct:
if v.unsafeSet != nil {
v.unsafeSet(add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset))
continue
}
// 目前是空的,预留下
if err := v.reflectSet(v.dstType, v.srcType, add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset), opt, &v); err != nil {
return err
}
// 处理slice
case kind == reflect.Slice:
// 由基础类型组成的slice
if v.unsafeSet != nil {
// 基础类型的slice直接一把函数搞定
v.unsafeSet(add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset))
continue
}
// 复合类型的slice
if v.reflectSet != nil {
if err := v.reflectSet(v.dstType, v.srcType, add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset), opt, &v); err != nil {
return err
}
}
// 处理map
case kind == reflect.Map:
// 基础类型的map直接一把函数搞定
if v.unsafeSet != nil {
v.unsafeSet(add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset))
continue
}
// 复合类型的map
if v.reflectSet != nil {
if err := v.reflectSet(v.dstType, v.srcType, add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset), opt, &v); err != nil {
return err
}
}
// 基础类型
case isBaseType(kind):
v.unsafeSet(add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset))
// 处理interface
case kind == reflect.Interface:
if v.reflectSet != nil {
// interface{}里面存放基础类型还是复合类型都由reflectSet函数处理
if err := v.reflectSet(v.dstType, v.srcType, add(dstBaseAddr, v.dstOffset), add(srcBaseAddr, v.srcOffset), opt, &v); err != nil {
return err
}
}
}
next:
if v.nextComposite != nil {
if err := v.nextComposite.do(dstBaseAddr, srcBaseAddr, opt); err != nil {
return err
}
continue
}
}
return nil
}
func addOffset(addr unsafe.Pointer, offset uintptr, i int) unsafe.Pointer {
return add(addr, int(offset)*i)
}
// 基址+offset
func add(addr unsafe.Pointer, offset int) unsafe.Pointer {
return unsafe.Pointer(uintptr(addr) + uintptr(offset))
}
// 基址-当前字段地址 求 offset
func sub(base uintptr, addr uintptr) int {
return int(base - uintptr(addr))
}