Skip to content

Commit

Permalink
Merge pull request kubernetes-sigs#4944 from ephesused/optimize-getan…
Browse files Browse the repository at this point in the history
…notations-2

Refactor mapping node traversal and optimize RNode.GetAnnotations and RNode.GetLabels
  • Loading branch information
k8s-ci-robot authored Jan 26, 2023
2 parents 279ad3e + a0e94c1 commit af9a131
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 109 deletions.
6 changes: 5 additions & 1 deletion api/internal/utils/makeResIds.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ func PrevIds(n *yaml.RNode) ([]resid.ResId, error) {
var ids []resid.ResId
// TODO: merge previous names and namespaces into one list of
// pairs on one annotation so there is no chance of error
annotations := n.GetAnnotations()
annotations := n.GetAnnotations(
BuildAnnotationPreviousNames,
BuildAnnotationPreviousNamespaces,
BuildAnnotationPreviousKinds)
if _, ok := annotations[BuildAnnotationPreviousNames]; !ok {
return nil, nil
}
Expand All @@ -51,6 +54,7 @@ func PrevIds(n *yaml.RNode) ([]resid.ResId, error) {
}
apiVersion := n.GetApiVersion()
group, version := resid.ParseGroupVersion(apiVersion)
ids = make([]resid.ResId, 0, len(names))
for i := range names {
gvk := resid.Gvk{
Group: group,
Expand Down
92 changes: 47 additions & 45 deletions kyaml/yaml/fns.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,36 +197,37 @@ func (c FieldClearer) Filter(rn *RNode) (*RNode, error) {
return nil, err
}

for i := 0; i < len(rn.Content()); i += 2 {
// if name matches, remove these 2 elements from the list because
// they are treated as a fieldName/fieldValue pair.
if rn.Content()[i].Value == c.Name {
if c.IfEmpty {
if len(rn.Content()[i+1].Content) > 0 {
continue
}
}
var removed *RNode
visitFieldsWhileTrue(rn.Content(), func(key, value *yaml.Node, keyIndex int) bool {
if key.Value != c.Name {
return true
}

// save the item we are about to remove
removed := NewRNode(rn.Content()[i+1])
if len(rn.YNode().Content) > i+2 {
l := len(rn.YNode().Content)
// remove from the middle of the list
rn.YNode().Content = rn.Content()[:i]
rn.YNode().Content = append(
rn.YNode().Content,
rn.Content()[i+2:l]...)
} else {
// remove from the end of the list
rn.YNode().Content = rn.Content()[:i]
// the name matches: remove these 2 elements from the list because
// they are treated as a fieldName/fieldValue pair.
if c.IfEmpty {
if len(value.Content) > 0 {
return true
}
}

// return the removed field name and value
return removed, nil
// save the item we are about to remove
removed = NewRNode(value)
if len(rn.YNode().Content) > keyIndex+2 {
l := len(rn.YNode().Content)
// remove from the middle of the list
rn.YNode().Content = rn.Content()[:keyIndex]
rn.YNode().Content = append(
rn.YNode().Content,
rn.Content()[keyIndex+2:l]...)
} else {
// remove from the end of the list
rn.YNode().Content = rn.Content()[:keyIndex]
}
}
// nothing removed
return nil, nil
return false
})

return removed, nil
}

func MatchElement(field, value string) ElementMatcher {
Expand Down Expand Up @@ -402,14 +403,15 @@ func (f FieldMatcher) Filter(rn *RNode) (*RNode, error) {
return nil, err
}

for i := 0; i < len(rn.Content()); i = IncrementFieldIndex(i) {
isMatchingField := rn.Content()[i].Value == f.Name
if isMatchingField {
requireMatchFieldValue := f.Value != nil
if !requireMatchFieldValue || rn.Content()[i+1].Value == f.Value.YNode().Value {
return NewRNode(rn.Content()[i+1]), nil
}
var returnNode *RNode
requireMatchFieldValue := f.Value != nil
visitMappingNodeFields(rn.Content(), func(key, value *yaml.Node) {
if !requireMatchFieldValue || value.Value == f.Value.YNode().Value {
returnNode = NewRNode(value)
}
}, f.Name)
if returnNode != nil {
return returnNode, nil
}

if f.Create != nil {
Expand Down Expand Up @@ -643,13 +645,19 @@ func (s MapEntrySetter) Filter(rn *RNode) (*RNode, error) {
if s.Name == "" {
s.Name = GetValue(s.Key)
}
for i := 0; i < len(rn.Content()); i = IncrementFieldIndex(i) {
isMatchingField := rn.Content()[i].Value == s.Name
if isMatchingField {
rn.Content()[i] = s.Key.YNode()
rn.Content()[i+1] = s.Value.YNode()
return rn, nil

content := rn.Content()
fieldStillNotFound := true
visitFieldsWhileTrue(content, func(key, value *yaml.Node, keyIndex int) bool {
if key.Value == s.Name {
content[keyIndex] = s.Key.YNode()
content[keyIndex+1] = s.Value.YNode()
fieldStillNotFound = false
}
return fieldStillNotFound
})
if !fieldStillNotFound {
return rn, nil
}

// create the field
Expand Down Expand Up @@ -868,9 +876,3 @@ func SplitIndexNameValue(p string) (string, string, error) {
}
return parts[0], parts[1], nil
}

// IncrementFieldIndex increments i to point to the next field name element in
// a slice of Contents.
func IncrementFieldIndex(i int) int {
return i + 2
}
Loading

0 comments on commit af9a131

Please sign in to comment.