Track keys during MiniYaml Merge.
This improves performance by avoiding repeated linear scans over the nodes to match the keys.
This commit is contained in:
@@ -338,22 +338,24 @@ namespace OpenRA
|
|||||||
return ResolveInherits(nodes, tree, new Dictionary<string, MiniYamlNode.SourceLocation>());
|
return ResolveInherits(nodes, tree, new Dictionary<string, MiniYamlNode.SourceLocation>());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MergeIntoResolved(MiniYamlNode overrideNode, List<MiniYamlNode> existingNodes,
|
static void MergeIntoResolved(MiniYamlNode overrideNode, List<MiniYamlNode> existingNodes, HashSet<string> existingNodeKeys,
|
||||||
Dictionary<string, MiniYaml> tree, Dictionary<string, MiniYamlNode.SourceLocation> inherited)
|
Dictionary<string, MiniYaml> tree, Dictionary<string, MiniYamlNode.SourceLocation> inherited)
|
||||||
{
|
{
|
||||||
var existingNode = existingNodes.Find(n => n.Key == overrideNode.Key);
|
if (existingNodeKeys.Add(overrideNode.Key))
|
||||||
if (existingNode != null)
|
|
||||||
{
|
{
|
||||||
|
existingNodes.Add(overrideNode.Clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingNode = existingNodes.Find(n => n.Key == overrideNode.Key);
|
||||||
existingNode.Value = MergePartial(existingNode.Value, overrideNode.Value);
|
existingNode.Value = MergePartial(existingNode.Value, overrideNode.Value);
|
||||||
existingNode.Value.Nodes = ResolveInherits(existingNode.Value, tree, inherited);
|
existingNode.Value.Nodes = ResolveInherits(existingNode.Value, tree, inherited);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
existingNodes.Add(overrideNode.Clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<MiniYamlNode> ResolveInherits(MiniYaml node, Dictionary<string, MiniYaml> tree, Dictionary<string, MiniYamlNode.SourceLocation> inherited)
|
static List<MiniYamlNode> ResolveInherits(MiniYaml node, Dictionary<string, MiniYaml> tree, Dictionary<string, MiniYamlNode.SourceLocation> inherited)
|
||||||
{
|
{
|
||||||
var resolved = new List<MiniYamlNode>(node.Nodes.Count);
|
var resolved = new List<MiniYamlNode>(node.Nodes.Count);
|
||||||
|
var resolvedKeys = new HashSet<string>(node.Nodes.Count);
|
||||||
|
|
||||||
// Inheritance is tracked from parent->child, but not from child->parentsiblings.
|
// Inheritance is tracked from parent->child, but not from child->parentsiblings.
|
||||||
inherited = new Dictionary<string, MiniYamlNode.SourceLocation>(inherited);
|
inherited = new Dictionary<string, MiniYamlNode.SourceLocation>(inherited);
|
||||||
@@ -371,16 +373,17 @@ namespace OpenRA
|
|||||||
|
|
||||||
inherited.Add(n.Value.Value, n.Location);
|
inherited.Add(n.Value.Value, n.Location);
|
||||||
foreach (var r in ResolveInherits(parent, tree, inherited))
|
foreach (var r in ResolveInherits(parent, tree, inherited))
|
||||||
MergeIntoResolved(r, resolved, tree, inherited);
|
MergeIntoResolved(r, resolved, resolvedKeys, tree, inherited);
|
||||||
}
|
}
|
||||||
else if (n.Key.StartsWith("-", StringComparison.Ordinal))
|
else if (n.Key.StartsWith("-", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
var removed = n.Key[1..];
|
var removed = n.Key[1..];
|
||||||
if (resolved.RemoveAll(r => r.Key == removed) == 0)
|
if (resolved.RemoveAll(r => r.Key == removed) == 0)
|
||||||
throw new YamlException($"{n.Location}: There are no elements with key `{removed}` to remove");
|
throw new YamlException($"{n.Location}: There are no elements with key `{removed}` to remove");
|
||||||
|
resolvedKeys.Remove(removed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MergeIntoResolved(n, resolved, tree, inherited);
|
MergeIntoResolved(n, resolved, resolvedKeys, tree, inherited);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved.TrimExcess();
|
resolved.TrimExcess();
|
||||||
|
|||||||
Reference in New Issue
Block a user