Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memoize DiffFieldReader.ReadField #15663

Merged
merged 1 commit into from
Aug 3, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions helper/schema/field_reader_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,59 @@ type DiffFieldReader struct {
Diff *terraform.InstanceDiff
Source FieldReader
Schema map[string]*Schema

// cache for memoizing ReadField calls.
cache map[string]cachedFieldReadResult
}

type cachedFieldReadResult struct {
val FieldReadResult
err error
}

func (r *DiffFieldReader) ReadField(address []string) (FieldReadResult, error) {
if r.cache == nil {
r.cache = make(map[string]cachedFieldReadResult)
}

// Create the cache key by joining around a value that isn't a valid part
// of an address. This assumes that the Source and Schema are not changed
// for the life of this DiffFieldReader.
cacheKey := strings.Join(address, "|")
if cached, ok := r.cache[cacheKey]; ok {
return cached.val, cached.err
}

schemaList := addrToSchema(address, r.Schema)
if len(schemaList) == 0 {
r.cache[cacheKey] = cachedFieldReadResult{}
return FieldReadResult{}, nil
}

var res FieldReadResult
var err error

schema := schemaList[len(schemaList)-1]
switch schema.Type {
case TypeBool, TypeInt, TypeFloat, TypeString:
return r.readPrimitive(address, schema)
res, err = r.readPrimitive(address, schema)
case TypeList:
return readListField(r, address, schema)
res, err = readListField(r, address, schema)
case TypeMap:
return r.readMap(address, schema)
res, err = r.readMap(address, schema)
case TypeSet:
return r.readSet(address, schema)
res, err = r.readSet(address, schema)
case typeObject:
return readObjectField(r, address, schema.Elem.(map[string]*Schema))
res, err = readObjectField(r, address, schema.Elem.(map[string]*Schema))
default:
panic(fmt.Sprintf("Unknown type: %#v", schema.Type))
}

r.cache[cacheKey] = cachedFieldReadResult{
val: res,
err: err,
}
return res, err
}

func (r *DiffFieldReader) readMap(
Expand Down