mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-13 22:38:04 +00:00
Significantly improved performance of exploding anchors (improves to json speed)
This commit is contained in:
parent
b55fe48bd8
commit
9624410add
94
cmd/utils.go
94
cmd/utils.go
@ -149,25 +149,91 @@ func writeString(writer io.Writer, txt string) error {
|
|||||||
return errorWriting
|
return errorWriting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setIfNotThere(node *yaml.Node, key string, value *yaml.Node) {
|
||||||
|
for index := 0; index < len(node.Content); index = index + 2 {
|
||||||
|
keyNode := node.Content[index]
|
||||||
|
if keyNode.Value == key {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// need to add it to the map
|
||||||
|
mapEntryKey := yaml.Node{Value: key, Kind: yaml.ScalarNode}
|
||||||
|
node.Content = append(node.Content, &mapEntryKey)
|
||||||
|
node.Content = append(node.Content, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyAlias(node *yaml.Node, alias *yaml.Node) {
|
||||||
|
for index := 0; index < len(alias.Content); index = index + 2 {
|
||||||
|
keyNode := alias.Content[index]
|
||||||
|
log.Debugf("applying alias key %v", keyNode.Value)
|
||||||
|
valueNode := alias.Content[index+1]
|
||||||
|
setIfNotThere(node, keyNode.Value, valueNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func explodeNode(node *yaml.Node) error {
|
||||||
|
node.Anchor = ""
|
||||||
|
switch node.Kind {
|
||||||
|
case yaml.SequenceNode, yaml.DocumentNode:
|
||||||
|
for index, contentNode := range node.Content {
|
||||||
|
log.Debugf("exploding index %v", index)
|
||||||
|
errorInContent := explodeNode(contentNode)
|
||||||
|
if errorInContent != nil {
|
||||||
|
return errorInContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case yaml.AliasNode:
|
||||||
|
log.Debugf("its an alias!")
|
||||||
|
node.Kind = node.Alias.Kind
|
||||||
|
node.Style = node.Alias.Style
|
||||||
|
node.Tag = node.Alias.Tag
|
||||||
|
node.Content = node.Alias.Content
|
||||||
|
node.Value = node.Alias.Value
|
||||||
|
node.Alias = nil
|
||||||
|
return nil
|
||||||
|
case yaml.MappingNode:
|
||||||
|
for index := 0; index < len(node.Content); index = index + 2 {
|
||||||
|
keyNode := node.Content[index]
|
||||||
|
valueNode := node.Content[index+1]
|
||||||
|
log.Debugf("traversing %v", keyNode.Value)
|
||||||
|
if keyNode.Value != "<<" {
|
||||||
|
errorInContent := explodeNode(valueNode)
|
||||||
|
if errorInContent != nil {
|
||||||
|
return errorInContent
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if valueNode.Kind == yaml.SequenceNode {
|
||||||
|
log.Debugf("an alias merge list!")
|
||||||
|
for index := len(valueNode.Content) - 1; index >= 0; index = index - 1 {
|
||||||
|
aliasNode := valueNode.Content[index]
|
||||||
|
applyAlias(node, aliasNode.Alias)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("an alias merge!")
|
||||||
|
applyAlias(node, valueNode.Alias)
|
||||||
|
}
|
||||||
|
node.Content = append(node.Content[:index], node.Content[index+2:]...)
|
||||||
|
//replay that index, since the array is shorter now.
|
||||||
|
index = index - 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func explode(matchingNodes []*yqlib.NodeContext) error {
|
func explode(matchingNodes []*yqlib.NodeContext) error {
|
||||||
log.Debug("exploding nodes")
|
log.Debug("exploding nodes")
|
||||||
for _, nodeContext := range matchingNodes {
|
for _, nodeContext := range matchingNodes {
|
||||||
var targetNode = yaml.Node{Kind: nodeContext.Node.Kind}
|
log.Debugf("exploding %v", nodeContext.Head)
|
||||||
explodedNodes, errorRetrieving := lib.Get(nodeContext.Node, "**", true)
|
errorExplodingNode := explodeNode(nodeContext.Node)
|
||||||
if errorRetrieving != nil {
|
if errorExplodingNode != nil {
|
||||||
return errorRetrieving
|
return errorExplodingNode
|
||||||
}
|
}
|
||||||
for _, matchingNode := range explodedNodes {
|
|
||||||
mergePath := lib.MergePathStackToString(matchingNode.PathStack, appendFlag)
|
|
||||||
updateCommand := yqlib.UpdateCommand{Command: "update", Path: mergePath, Value: matchingNode.Node, Overwrite: overwriteFlag}
|
|
||||||
errorUpdating := lib.Update(&targetNode, updateCommand, true)
|
|
||||||
if errorUpdating != nil {
|
|
||||||
return errorUpdating
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nodeContext.Node = &targetNode
|
|
||||||
}
|
}
|
||||||
log.Debug("done exploding nodes")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user