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(
result[k] = v.New
}
- err = mapValuesToPrimitive(result, schema)
+ key := address[len(address)-1]
+ err = mapValuesToPrimitive(key, result, schema)
if err != nil {
return FieldReadResult{}, nil
}