...
1
16
17 package value
18
19
20
21
22
23
24 type Allocator interface {
25
26
27
28 Free(interface{})
29
30
31
32 allocValueUnstructured() *valueUnstructured
33 allocListUnstructuredRange() *listUnstructuredRange
34 allocValueReflect() *valueReflect
35 allocMapReflect() *mapReflect
36 allocStructReflect() *structReflect
37 allocListReflect() *listReflect
38 allocListReflectRange() *listReflectRange
39 }
40
41
42
43
44
45 var HeapAllocator = &heapAllocator{}
46
47 type heapAllocator struct{}
48
49 func (p *heapAllocator) allocValueUnstructured() *valueUnstructured {
50 return &valueUnstructured{}
51 }
52
53 func (p *heapAllocator) allocListUnstructuredRange() *listUnstructuredRange {
54 return &listUnstructuredRange{vv: &valueUnstructured{}}
55 }
56
57 func (p *heapAllocator) allocValueReflect() *valueReflect {
58 return &valueReflect{}
59 }
60
61 func (p *heapAllocator) allocStructReflect() *structReflect {
62 return &structReflect{}
63 }
64
65 func (p *heapAllocator) allocMapReflect() *mapReflect {
66 return &mapReflect{}
67 }
68
69 func (p *heapAllocator) allocListReflect() *listReflect {
70 return &listReflect{}
71 }
72
73 func (p *heapAllocator) allocListReflectRange() *listReflectRange {
74 return &listReflectRange{vr: &valueReflect{}}
75 }
76
77 func (p *heapAllocator) Free(_ interface{}) {}
78
79
80
81
82
83
84
85
86
87
88
89
90 func NewFreelistAllocator() Allocator {
91 return &freelistAllocator{
92 valueUnstructured: &freelist{new: func() interface{} {
93 return &valueUnstructured{}
94 }},
95 listUnstructuredRange: &freelist{new: func() interface{} {
96 return &listUnstructuredRange{vv: &valueUnstructured{}}
97 }},
98 valueReflect: &freelist{new: func() interface{} {
99 return &valueReflect{}
100 }},
101 mapReflect: &freelist{new: func() interface{} {
102 return &mapReflect{}
103 }},
104 structReflect: &freelist{new: func() interface{} {
105 return &structReflect{}
106 }},
107 listReflect: &freelist{new: func() interface{} {
108 return &listReflect{}
109 }},
110 listReflectRange: &freelist{new: func() interface{} {
111 return &listReflectRange{vr: &valueReflect{}}
112 }},
113 }
114 }
115
116
117
118
119 const freelistMaxSize = 1000
120
121 type freelistAllocator struct {
122 valueUnstructured *freelist
123 listUnstructuredRange *freelist
124 valueReflect *freelist
125 mapReflect *freelist
126 structReflect *freelist
127 listReflect *freelist
128 listReflectRange *freelist
129 }
130
131 type freelist struct {
132 list []interface{}
133 new func() interface{}
134 }
135
136 func (f *freelist) allocate() interface{} {
137 var w2 interface{}
138 if n := len(f.list); n > 0 {
139 w2, f.list = f.list[n-1], f.list[:n-1]
140 } else {
141 w2 = f.new()
142 }
143 return w2
144 }
145
146 func (f *freelist) free(v interface{}) {
147 if len(f.list) < freelistMaxSize {
148 f.list = append(f.list, v)
149 }
150 }
151
152 func (w *freelistAllocator) Free(value interface{}) {
153 switch v := value.(type) {
154 case *valueUnstructured:
155 v.Value = nil
156 w.valueUnstructured.free(v)
157 case *listUnstructuredRange:
158 v.vv.Value = nil
159 w.listUnstructuredRange.free(v)
160 case *valueReflect:
161 v.ParentMapKey = nil
162 v.ParentMap = nil
163 w.valueReflect.free(v)
164 case *mapReflect:
165 w.mapReflect.free(v)
166 case *structReflect:
167 w.structReflect.free(v)
168 case *listReflect:
169 w.listReflect.free(v)
170 case *listReflectRange:
171 v.vr.ParentMapKey = nil
172 v.vr.ParentMap = nil
173 w.listReflectRange.free(v)
174 }
175 }
176
177 func (w *freelistAllocator) allocValueUnstructured() *valueUnstructured {
178 return w.valueUnstructured.allocate().(*valueUnstructured)
179 }
180
181 func (w *freelistAllocator) allocListUnstructuredRange() *listUnstructuredRange {
182 return w.listUnstructuredRange.allocate().(*listUnstructuredRange)
183 }
184
185 func (w *freelistAllocator) allocValueReflect() *valueReflect {
186 return w.valueReflect.allocate().(*valueReflect)
187 }
188
189 func (w *freelistAllocator) allocStructReflect() *structReflect {
190 return w.structReflect.allocate().(*structReflect)
191 }
192
193 func (w *freelistAllocator) allocMapReflect() *mapReflect {
194 return w.mapReflect.allocate().(*mapReflect)
195 }
196
197 func (w *freelistAllocator) allocListReflect() *listReflect {
198 return w.listReflect.allocate().(*listReflect)
199 }
200
201 func (w *freelistAllocator) allocListReflectRange() *listReflectRange {
202 return w.listReflectRange.allocate().(*listReflectRange)
203 }
204
View as plain text