in pkg/log/structure/merger/merged.go [298:455]
func (d *StrategicMergedStructureData) buildArrayMergeResultSourceCache() error {
d.arrayMergeResultSourceCache = &arrayMergeResultSourceCache{
References: make([]*arrayMergeResultElementReference, 0),
}
patchKeys, err := d.patch.Keys()
if err != nil {
return err
}
strategy := d.mergeKeyResolver.GetMergeArrayStrategy(d.path)
if strategy == MergeStrategyReplace {
for _, key := range patchKeys {
d.arrayMergeResultSourceCache.References = append(d.arrayMergeResultSourceCache.References, &arrayMergeResultElementReference{
From: d.patch,
Index: key,
})
}
} else {
mergeKey, err := d.mergeKeyResolver.GetMergeKey(d.path)
if err != nil {
return err
}
patchElements, err := d.splitPatchKeysByElementsOrMergeAttributesInArray(d.patch)
if err != nil {
return err
}
if patchElements.Replace {
for _, elem := range patchElements.Elements {
d.arrayMergeResultSourceCache.References = append(d.arrayMergeResultSourceCache.References, &arrayMergeResultElementReference{
From: elem,
Index: "",
})
}
return nil
}
prevFields := []structuredata.StructureData{}
prevKeys, err := d.prev.Keys()
if err != nil {
return err
}
if len(prevKeys) == 1 && prevKeys[0] == "" {
// The previous value is nil
} else {
for _, key := range prevKeys {
vany, err := d.prev.Value(key)
if err != nil {
return err
}
vst, convertible := vany.(structuredata.StructureData)
if !convertible {
return fmt.Errorf("expected vany to be convertible to structuredata, but didn't")
}
prevFields = append(prevFields, vst)
}
}
prevFieldsKeyOrder := []string{}
prevFieldsMap := map[string]structuredata.StructureData{}
for _, field := range prevFields {
keyValue, err := d.readScalar(field, mergeKey)
if err != nil {
return fmt.Errorf("merge key %s not found in prev field map", mergeKey)
}
hash, err := toHash(keyValue)
if err != nil {
return err
}
prevFieldsKeyOrder = append(prevFieldsKeyOrder, hash)
prevFieldsMap[hash] = field
}
patchFieldKeyOrder := []string{}
patchFieldMap := map[string]structuredata.StructureData{}
for _, field := range patchElements.Elements {
keyValue, err := d.readScalar(field, mergeKey)
if err != nil {
return fmt.Errorf("merge key %s not found in patch field map", mergeKey)
}
hash, err := toHash(keyValue)
if err != nil {
return err
}
patchFieldKeyOrder = append(patchFieldKeyOrder, hash)
patchFieldMap[hash] = field
}
deletedMap := map[string]struct{}{}
if d.deleteFromPrimitiveListDirective != nil {
for _, primitive := range d.deleteFromPrimitiveListDirective.list {
hash, err := toHash(primitive)
if err != nil {
return err
}
deletedMap[hash] = struct{}{}
}
}
for _, field := range patchElements.DeletedFields {
key, err := d.readScalarAsString(field, mergeKey)
if err != nil {
return err
}
deletedMap[key] = struct{}{}
}
keydiff := NewKeyDiffForArrayMerge(prevFieldsKeyOrder, patchFieldKeyOrder)
setElementOrderKeys := []string{}
if d.setElementOrderDirective != nil {
for _, orderKeyValue := range d.setElementOrderDirective.list {
if structuredata, convertible := orderKeyValue.(structuredata.StructureData); convertible {
orderKeyValue, err = d.readScalar(structuredata, mergeKey)
if err != nil {
return err
}
}
hash, err := toHash(orderKeyValue)
if err != nil {
return err
}
setElementOrderKeys = append(setElementOrderKeys, hash)
}
}
orderedKeys := reorderArrayKeysForMerge(prevFieldsKeyOrder, patchFieldKeyOrder, setElementOrderKeys)
bothKeys := map[string]struct{}{}
for _, key := range keydiff.Both {
bothKeys[key] = struct{}{}
}
for _, key := range orderedKeys {
if _, found := deletedMap[key]; found {
continue
}
if _, found := bothKeys[key]; found {
d.arrayMergeResultSourceCache.References = append(d.arrayMergeResultSourceCache.References, &arrayMergeResultElementReference{
From: NewStrategicMergedStructureData(d.path+"[]", prevFieldsMap[key], patchFieldMap[key], d.mergeKeyResolver),
Index: "",
})
continue
}
if _, found := patchFieldMap[key]; found {
d.arrayMergeResultSourceCache.References = append(d.arrayMergeResultSourceCache.References, &arrayMergeResultElementReference{
From: patchFieldMap[key],
Index: "",
})
continue
}
if _, found := prevFieldsMap[key]; found {
d.arrayMergeResultSourceCache.References = append(d.arrayMergeResultSourceCache.References, &arrayMergeResultElementReference{
From: prevFieldsMap[key],
Index: "",
})
continue
}
complemented, err := structuredata.DataFromYaml(fmt.Sprintf("%s: %s", mergeKey, key))
if err != nil {
return err
}
d.arrayMergeResultSourceCache.References = append(d.arrayMergeResultSourceCache.References, &arrayMergeResultElementReference{
From: complemented,
Index: "",
})
}
}
return nil
}