github.com/wfusion/gofusion@v1.1.14/common/utils/clone/allocatormethods.go (about) 1 // Copyright 2023 Huan Du. All rights reserved. 2 // Licensed under the MIT license that can be found in the LICENSE file. 3 4 package clone 5 6 import ( 7 "reflect" 8 "unsafe" 9 ) 10 11 // AllocatorMethods defines all methods required by allocator. 12 // If any of these methods is nil, allocator will use default method which allocates memory from heap. 13 type AllocatorMethods struct { 14 // Parent is the allocator which handles all unhandled methods. 15 // If it's nil, it will be the default allocator. 16 Parent *Allocator 17 18 New func(pool unsafe.Pointer, t reflect.Type) reflect.Value 19 MakeSlice func(pool unsafe.Pointer, t reflect.Type, len, cap int) reflect.Value 20 MakeMap func(pool unsafe.Pointer, t reflect.Type, n int) reflect.Value 21 MakeChan func(pool unsafe.Pointer, t reflect.Type, buffer int) reflect.Value 22 IsScalar func(k reflect.Kind) bool 23 } 24 25 func (am *AllocatorMethods) parent() *Allocator { 26 if am != nil && am.Parent != nil { 27 return am.Parent 28 } 29 30 return nil 31 } 32 33 func (am *AllocatorMethods) new(parent *Allocator, pool unsafe.Pointer) func(pool unsafe.Pointer, t reflect.Type) reflect.Value { 34 if am != nil && am.New != nil { 35 return am.New 36 } 37 38 if parent != nil { 39 if parent.pool == pool { 40 return parent.new 41 } else { 42 return func(pool unsafe.Pointer, t reflect.Type) reflect.Value { 43 return parent.New(t) 44 } 45 } 46 } 47 48 return defaultAllocator.new 49 } 50 51 func (am *AllocatorMethods) makeSlice(parent *Allocator, pool unsafe.Pointer) func(pool unsafe.Pointer, t reflect.Type, len, cap int) reflect.Value { 52 if am != nil && am.MakeSlice != nil { 53 return am.MakeSlice 54 } 55 56 if parent != nil { 57 if parent.pool == pool { 58 return parent.makeSlice 59 } else { 60 return func(pool unsafe.Pointer, t reflect.Type, len, cap int) reflect.Value { 61 return parent.MakeSlice(t, len, cap) 62 } 63 } 64 } 65 66 return defaultAllocator.makeSlice 67 } 68 69 func (am *AllocatorMethods) makeMap(parent *Allocator, pool unsafe.Pointer) func(pool unsafe.Pointer, t reflect.Type, n int) reflect.Value { 70 if am != nil && am.MakeMap != nil { 71 return am.MakeMap 72 } 73 74 if parent != nil { 75 if parent.pool == pool { 76 return parent.makeMap 77 } else { 78 return func(pool unsafe.Pointer, t reflect.Type, n int) reflect.Value { 79 return parent.MakeMap(t, n) 80 } 81 } 82 } 83 84 return defaultAllocator.makeMap 85 } 86 87 func (am *AllocatorMethods) makeChan(parent *Allocator, pool unsafe.Pointer) func(pool unsafe.Pointer, t reflect.Type, buffer int) reflect.Value { 88 if am != nil && am.MakeChan != nil { 89 return am.MakeChan 90 } 91 92 if parent != nil { 93 if parent.pool == pool { 94 return parent.makeChan 95 } else { 96 return func(pool unsafe.Pointer, t reflect.Type, buffer int) reflect.Value { 97 return parent.MakeChan(t, buffer) 98 } 99 } 100 } 101 102 return defaultAllocator.makeChan 103 } 104 105 func (am *AllocatorMethods) isScalar(parent *Allocator) func(t reflect.Kind) bool { 106 if am != nil && am.IsScalar != nil { 107 return am.IsScalar 108 } 109 110 if parent != nil { 111 return parent.isScalar 112 } 113 114 return defaultAllocator.isScalar 115 }