From 83652f59db7639bcc477d45132eb393a06cb4de8 Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Thu, 3 Aug 2017 15:11:34 +0200 Subject: [PATCH] Actually cache the drop resolution --- values/drop.go | 35 ++++++++++++++--------------------- values/value.go | 2 +- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/values/drop.go b/values/drop.go index c768961..6c1b372 100644 --- a/values/drop.go +++ b/values/drop.go @@ -1,6 +1,8 @@ package values -import "sync" +import ( + "sync" +) type drop interface { ToLiquid() interface{} @@ -16,31 +18,22 @@ func ToLiquid(value interface{}) interface{} { } } -// embed this in a struct to give it default implementations of the Value interface type dropWrapper struct { d drop v Value + sync.Once } -// Single mutex, until proven finer granularity helps. -var dropResolverMu sync.Mutex - -func (w dropWrapper) Resolve() Value { - if w.v == nil { - dropResolverMu.Lock() - defer dropResolverMu.Unlock() - if w.v == nil { - w.v = ValueOf(w.d.ToLiquid()) - } - } +func (w *dropWrapper) Resolve() Value { + w.Do(func() { w.v = ValueOf(w.d.ToLiquid()) }) return w.v } -func (w dropWrapper) Equal(o Value) bool { return w.Resolve().Equal(o) } -func (w dropWrapper) Less(o Value) bool { return w.Resolve().Less(o) } -func (w dropWrapper) IndexValue(i Value) Value { return w.Resolve().IndexValue(i) } -func (w dropWrapper) Contains(o Value) bool { return w.Resolve().Contains(o) } -func (w dropWrapper) Int() int { return w.Resolve().Int() } -func (w dropWrapper) Interface() interface{} { return w.Resolve().Interface() } -func (w dropWrapper) PropertyValue(k Value) Value { return w.Resolve().PropertyValue(k) } -func (w dropWrapper) Test() bool { return w.Resolve().Test() } +func (w *dropWrapper) Equal(o Value) bool { return w.Resolve().Equal(o) } +func (w *dropWrapper) Less(o Value) bool { return w.Resolve().Less(o) } +func (w *dropWrapper) IndexValue(i Value) Value { return w.Resolve().IndexValue(i) } +func (w *dropWrapper) Contains(o Value) bool { return w.Resolve().Contains(o) } +func (w *dropWrapper) Int() int { return w.Resolve().Int() } +func (w *dropWrapper) Interface() interface{} { return w.Resolve().Interface() } +func (w *dropWrapper) PropertyValue(k Value) Value { return w.Resolve().PropertyValue(k) } +func (w *dropWrapper) Test() bool { return w.Resolve().Test() } diff --git a/values/value.go b/values/value.go index 1bfee83..1ce993a 100644 --- a/values/value.go +++ b/values/value.go @@ -41,7 +41,7 @@ func ValueOf(value interface{}) Value { // nolint: gocyclo // interfaces switch v := value.(type) { case drop: - return dropWrapper{d: v} + return &dropWrapper{d: v} case yaml.MapSlice: return mapSliceValue{slice: v} case Value: