github.com/lxt1045/json@v0.0.0-20231013032136-54d6b1d6e525/type_builder.go (about) 1 // MIT License 2 // 3 // Copyright (c) 2021 Xiantu Li 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 // SOFTWARE. 22 23 package json 24 25 import ( 26 "fmt" 27 "reflect" 28 "sync" 29 "unsafe" 30 ) 31 32 // 构造器 33 type TypeBuilder struct { 34 // 用于存储属性字段 35 fields []reflect.StructField 36 Type reflect.Type 37 lazyOffsets []*uintptr 38 39 goType *GoType 40 size int 41 pool sync.Pool 42 } 43 44 func NewTypeBuilder() *TypeBuilder { 45 return &TypeBuilder{} 46 } 47 48 // 根据预先添加的字段构建出结构体 49 func (b *TypeBuilder) New() unsafe.Pointer { 50 v := reflect.New(b.Type) 51 p := reflectValueToPointer(&v) 52 return p 53 } 54 55 // 根据预先添加的字段构建出结构体 56 func (b *TypeBuilder) NewSlice() unsafe.Pointer { 57 p := unsafe_NewArray(b.goType, 1024) 58 return p 59 } 60 61 func (b *TypeBuilder) Interface() interface{} { 62 v := reflect.New(b.Type) 63 return v.Interface() 64 } 65 func (b *TypeBuilder) PInterface() (unsafe.Pointer, interface{}) { 66 v := reflect.New(b.Type) 67 return reflectValueToPointer(&v), v.Interface() 68 } 69 70 // 根据预先添加的字段构建出结构体 71 func (b *TypeBuilder) Build() reflect.Type { 72 if len(b.fields) == 0 { 73 return nil 74 } 75 typ := b.Type 76 if b.Type == nil { 77 typ = reflect.StructOf(b.fields) 78 b.Type = typ 79 b.goType = UnpackType(typ) 80 } 81 for i := 0; i < typ.NumField(); i++ { 82 if len(b.lazyOffsets) > i && b.lazyOffsets[i] != nil { 83 *b.lazyOffsets[i] = typ.Field(i).Offset 84 } 85 } 86 return typ 87 } 88 89 //Init 调用 Build() 并初始化缓存 90 func (b *TypeBuilder) Init() { 91 b.Build() 92 93 // 处理缓存 94 if len(b.fields) == 0 { 95 return 96 } 97 goType := b.goType 98 b.size = int(goType.Size) 99 N := (8 * 1024 / b.size) + 1 100 l := N * b.size 101 b.pool.New = func() any { 102 // reflect.MakeSlice() 103 ps := unsafe_NewArray(goType, N) 104 pH := &SliceHeader{ 105 Data: ps, 106 Len: l, 107 Cap: l, 108 } 109 return (*[]uint8)(unsafe.Pointer(pH)) 110 } 111 } 112 113 // TODO: 此处也可以使用 NewBatch 来提高性能? 提升 10ns ? 114 func (b *TypeBuilder) NewFromPool() unsafe.Pointer { 115 if len(b.fields) == 0 { 116 return nil 117 } 118 s := b.pool.Get().(*[]uint8) 119 pp := unsafe.Pointer(&(*s)[0]) 120 if cap(*s) >= b.size*2 { 121 *s = (*s)[b.size:] 122 b.pool.Put(s) 123 } 124 return pp 125 } 126 127 /* 128 针对 slice,要添加一个 [4]type 的空间作为预分配的资源 129 */ 130 func (b *TypeBuilder) AppendTagField(typ reflect.Type, lazyOffset *uintptr) *TypeBuilder { 131 name := fmt.Sprintf("F_%d", len(b.fields)) 132 b.fields = append(b.fields, reflect.StructField{Name: name, Type: typ}) 133 b.lazyOffsets = append(b.lazyOffsets, lazyOffset) 134 return b 135 } 136 137 func (b *TypeBuilder) AppendField(name string, typ reflect.Type, lazyOffset *uintptr) *TypeBuilder { 138 b.fields = append(b.fields, reflect.StructField{Name: name, Type: typ}) 139 b.lazyOffsets = append(b.lazyOffsets, lazyOffset) 140 return b 141 } 142 143 func (b *TypeBuilder) AppendPointer(name string, lazyOffset *uintptr) *TypeBuilder { 144 var p unsafe.Pointer 145 return b.AppendField(name, reflect.TypeOf(p), lazyOffset) 146 } 147 148 func (b *TypeBuilder) AppendIntSlice(name string, lazyOffset *uintptr) *TypeBuilder { 149 var s []int 150 return b.AppendField(name, reflect.TypeOf(s), lazyOffset) 151 } 152 153 func (b *TypeBuilder) AppendString(name string, lazyOffset *uintptr) *TypeBuilder { 154 return b.AppendField(name, reflect.TypeOf(""), lazyOffset) 155 } 156 157 func (b *TypeBuilder) AppendBool(name string, lazyOffset *uintptr) *TypeBuilder { 158 return b.AppendField(name, reflect.TypeOf(true), lazyOffset) 159 } 160 161 func (b *TypeBuilder) AppendInt64(name string, lazyOffset *uintptr) *TypeBuilder { 162 return b.AppendField(name, reflect.TypeOf(int64(0)), lazyOffset) 163 } 164 165 func (b *TypeBuilder) AppendFloat64(name string, lazyOffset *uintptr) *TypeBuilder { 166 return b.AppendField(name, reflect.TypeOf(float64(1.2)), lazyOffset) 167 } 168 169 // 添加字段 170 func (b *TypeBuilder) AddField(field string, typ reflect.Type) *TypeBuilder { 171 b.fields = append(b.fields, reflect.StructField{Name: field, Type: typ}) 172 return b 173 } 174 175 func (b *TypeBuilder) AddString(name string) *TypeBuilder { 176 return b.AddField(name, reflect.TypeOf("")) 177 } 178 179 func (b *TypeBuilder) AddBool(name string) *TypeBuilder { 180 return b.AddField(name, reflect.TypeOf(true)) 181 } 182 183 func (b *TypeBuilder) AddInt64(name string) *TypeBuilder { 184 return b.AddField(name, reflect.TypeOf(int64(0))) 185 } 186 187 func (b *TypeBuilder) AddFloat64(name string) *TypeBuilder { 188 return b.AddField(name, reflect.TypeOf(float64(1.2))) 189 } 190 191 func main() { 192 b := NewTypeBuilder(). 193 AddString("Name"). 194 AddInt64("Age") 195 196 p := b.New() 197 i := b.Interface() 198 pp := reflect.ValueOf(i).Elem().Addr().Interface() 199 fmt.Printf("typ:%T, value:%+v, ponter1:%d,ponter1:%v\n", p, i, p, pp) 200 }