Skip to content

Commit 4e4c7eb

Browse files
committed
memory pools for walkers
1 parent 53f1aee commit 4e4c7eb

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 {
@@ -203,6 +207,10 @@ func (tv TypedValue) Empty() *TypedValue {
203207
return &tv
204208
}
205209

210+
var mwPool = sync.Pool{
211+
New: func() interface{} { return &mergingWalker{} },
212+
}
213+
206214
func merge(lhs, rhs *TypedValue, rule, postRule mergeRule) (*TypedValue, error) {
207215
if lhs.schema != rhs.schema {
208216
return nil, errorFormatter{}.
@@ -213,14 +221,27 @@ func merge(lhs, rhs *TypedValue, rule, postRule mergeRule) (*TypedValue, error)
213221
errorf("expected objects of the same type, but got %v and %v", lhs.typeRef, rhs.typeRef)
214222
}
215223

216-
mw := mergingWalker{
217-
lhs: &lhs.value,
218-
rhs: &rhs.value,
219-
schema: lhs.schema,
220-
typeRef: lhs.typeRef,
221-
rule: rule,
222-
postItemHook: postRule,
223-
}
224+
mw := mwPool.Get().(*mergingWalker)
225+
defer func() {
226+
mw.lhs = nil
227+
mw.rhs = nil
228+
mw.schema = nil
229+
mw.typeRef = schema.TypeRef{}
230+
mw.rule = nil
231+
mw.postItemHook = nil
232+
mw.out = nil
233+
mw.inLeaf = false
234+
235+
mwPool.Put(mw)
236+
}()
237+
238+
mw.lhs = &lhs.value
239+
mw.rhs = &rhs.value
240+
mw.schema = lhs.schema
241+
mw.typeRef = lhs.typeRef
242+
mw.rule = rule
243+
mw.postItemHook = postRule
244+
224245
errs := mw.merge()
225246
if len(errs) > 0 {
226247
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)