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
|
package hm
import "sync"
const (
poolSize = 4
extraCap = 2
)
var sSubPool = [poolSize]*sync.Pool{
&sync.Pool{
New: func() interface{} { return &sSubs{s: make([]Substitution, 1, 1+extraCap)} },
},
&sync.Pool{
New: func() interface{} { return &sSubs{s: make([]Substitution, 2, 2+extraCap)} },
},
&sync.Pool{
New: func() interface{} { return &sSubs{s: make([]Substitution, 3, 3+extraCap)} },
},
&sync.Pool{
New: func() interface{} { return &sSubs{s: make([]Substitution, 4, 4+extraCap)} },
},
}
var mSubPool = &sync.Pool{
New: func() interface{} { return make(mSubs) },
}
// ReturnSubs returns substitutions to the pool. USE WITH CAUTION.
func ReturnSubs(sub Subs) {
switch s := sub.(type) {
case mSubs:
for k := range s {
delete(s, k)
}
mSubPool.Put(sub)
case *sSubs:
size := cap(s.s) - 2
if size > 0 && size < poolSize+1 {
// reset to empty
for i := range s.s {
s.s[i] = Substitution{}
}
s.s = s.s[:size]
sSubPool[size-1].Put(sub)
}
}
}
// BorrowMSubs gets a map based substitution from a shared pool. USE WITH CAUTION
func BorrowMSubs() mSubs {
return mSubPool.Get().(mSubs)
}
// BorrowSSubs gets a slice based substituiton from a shared pool. USE WITH CAUTION
func BorrowSSubs(size int) *sSubs {
if size > 0 && size < 5 {
retVal := sSubPool[size-1].Get().(*sSubs)
return retVal
}
s := make([]Substitution, size)
return &sSubs{s: s}
}
var typesPool = [poolSize]*sync.Pool{
&sync.Pool{
New: func() interface{} { return make(Types, 1) },
},
&sync.Pool{
New: func() interface{} { return make(Types, 2) },
},
&sync.Pool{
New: func() interface{} { return make(Types, 3) },
},
&sync.Pool{
New: func() interface{} { return make(Types, 4) },
},
}
// BorrowTypes gets a slice of Types with size. USE WITH CAUTION.
func BorrowTypes(size int) Types {
if size > 0 && size < poolSize+1 {
return typesPool[size-1].Get().(Types)
}
return make(Types, size)
}
// ReturnTypes returns the slice of types into the pool. USE WITH CAUTION
func ReturnTypes(ts Types) {
if size := cap(ts); size > 0 && size < poolSize+1 {
ts = ts[:cap(ts)]
for i := range ts {
ts[i] = nil
}
typesPool[size-1].Put(ts)
}
}
var typeVarSetPool = [poolSize]*sync.Pool{
&sync.Pool{
New: func() interface{} { return make(TypeVarSet, 1) },
},
&sync.Pool{
New: func() interface{} { return make(TypeVarSet, 2) },
},
&sync.Pool{
New: func() interface{} { return make(TypeVarSet, 3) },
},
&sync.Pool{
New: func() interface{} { return make(TypeVarSet, 4) },
},
}
// BorrowTypeVarSet gets a TypeVarSet of size from pool. USE WITH CAUTION
func BorrowTypeVarSet(size int) TypeVarSet {
if size > 0 && size < poolSize+1 {
return typeVarSetPool[size-1].Get().(TypeVarSet)
}
return make(TypeVarSet, size)
}
// ReturnTypeVarSet returns the TypeVarSet to pool. USE WITH CAUTION
func ReturnTypeVarSet(ts TypeVarSet) {
var def TypeVariable
if size := cap(ts); size > 0 && size < poolSize+1 {
ts = ts[:cap(ts)]
for i := range ts {
ts[i] = def
}
typeVarSetPool[size-1].Put(ts)
}
}
var fnTypePool = &sync.Pool{
New: func() interface{} { return new(FunctionType) },
}
func borrowFnType() *FunctionType {
return fnTypePool.Get().(*FunctionType)
}
// ReturnFnType returns a *FunctionType to the pool. NewFnType automatically borrows from the pool. USE WITH CAUTION
func ReturnFnType(fnt *FunctionType) {
if a, ok := fnt.a.(*FunctionType); ok {
ReturnFnType(a)
}
if b, ok := fnt.b.(*FunctionType); ok {
ReturnFnType(b)
}
fnt.a = nil
fnt.b = nil
fnTypePool.Put(fnt)
}
|