Skip to content

Commit 78536ba

Browse files
authored
Merge pull request #97 from lavalamp/mempool
memory pools for walkers
2 parents 348b25d + 4e4c7eb commit 78536ba

File tree

2 files changed

+51
-14
lines changed

2 files changed

+51
-14
lines changed

typed/typed.go

+30-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package typed
1818

1919
import (
2020
"fmt"
21+
"sync"
2122

2223
"sigs.k8s.io/structured-merge-diff/fieldpath"
2324
"sigs.k8s.io/structured-merge-diff/schema"
@@ -66,7 +67,9 @@ func (tv TypedValue) AsValue() *value.Value {
6667

6768
// Validate returns an error with a list of every spec violation.
6869
func (tv TypedValue) Validate() error {
69-
if errs := tv.walker().validate(); len(errs) != 0 {
70+
w := tv.walker()
71+
defer w.finished()
72+
if errs := w.validate(); len(errs) != 0 {
7073
return errs
7174
}
7275
return nil
@@ -77,6 +80,7 @@ func (tv TypedValue) Validate() error {
7780
func (tv TypedValue) ToFieldSet() (*fieldpath.Set, error) {
7881
s := fieldpath.NewSet()
7982
w := tv.walker()
83+
defer w.finished()
8084
w.leafFieldCallback = func(p fieldpath.Path) { s.Insert(p) }
8185
w.nodeFieldCallback = func(p fieldpath.Path) { s.Insert(p) }
8286
if errs := w.validate(); len(errs) != 0 {
@@ -207,6 +211,10 @@ func (tv TypedValue) Empty() *TypedValue {
207211
return &tv
208212
}
209213

214+
var mwPool = sync.Pool{
215+
New: func() interface{} { return &mergingWalker{} },
216+
}
217+
210218
func merge(lhs, rhs *TypedValue, rule, postRule mergeRule) (*TypedValue, error) {
211219
if lhs.schema != rhs.schema {
212220
return nil, errorFormatter{}.
@@ -217,14 +225,27 @@ func merge(lhs, rhs *TypedValue, rule, postRule mergeRule) (*TypedValue, error)
217225
errorf("expected objects of the same type, but got %v and %v", lhs.typeRef, rhs.typeRef)
218226
}
219227

220-
mw := mergingWalker{
221-
lhs: &lhs.value,
222-
rhs: &rhs.value,
223-
schema: lhs.schema,
224-
typeRef: lhs.typeRef,
225-
rule: rule,
226-
postItemHook: postRule,
227-
}
228+
mw := mwPool.Get().(*mergingWalker)
229+
defer func() {
230+
mw.lhs = nil
231+
mw.rhs = nil
232+
mw.schema = nil
233+
mw.typeRef = schema.TypeRef{}
234+
mw.rule = nil
235+
mw.postItemHook = nil
236+
mw.out = nil
237+
mw.inLeaf = false
238+
239+
mwPool.Put(mw)
240+
}()
241+
242+
mw.lhs = &lhs.value
243+
mw.rhs = &rhs.value
244+
mw.schema = lhs.schema
245+
mw.typeRef = lhs.typeRef
246+
mw.rule = rule
247+
mw.postItemHook = postRule
248+
228249
errs := mw.merge()
229250
if len(errs) > 0 {
230251
return nil, errs

typed/validate.go

+21-5
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,33 @@ limitations under the License.
1717
package typed
1818

1919
import (
20+
"sync"
21+
2022
"sigs.k8s.io/structured-merge-diff/fieldpath"
2123
"sigs.k8s.io/structured-merge-diff/schema"
2224
"sigs.k8s.io/structured-merge-diff/value"
2325
)
2426

27+
var vPool = sync.Pool{
28+
New: func() interface{} { return &validatingObjectWalker{} },
29+
}
30+
2531
func (tv TypedValue) walker() *validatingObjectWalker {
26-
return &validatingObjectWalker{
27-
value: tv.value,
28-
schema: tv.schema,
29-
typeRef: tv.typeRef,
30-
}
32+
v := vPool.Get().(*validatingObjectWalker)
33+
v.value = tv.value
34+
v.schema = tv.schema
35+
v.typeRef = tv.typeRef
36+
return v
37+
}
38+
39+
func (v *validatingObjectWalker) finished() {
40+
v.value = value.Value{}
41+
v.schema = nil
42+
v.typeRef = schema.TypeRef{}
43+
v.leafFieldCallback = nil
44+
v.nodeFieldCallback = nil
45+
v.inLeaf = false
46+
vPool.Put(v)
3147
}
3248

3349
type validatingObjectWalker struct {

0 commit comments

Comments
 (0)