private static CompositPropertyVertex OptimizeNode(PropertyInfoVertex node, PathBuilderSearchCache cache) { CompositPropertyVertex composite; if (cache.AllCompositProperties.TryGetValue(node.Property, out composite)) { return(composite); } composite = new CompositPropertyVertex(); cache.AllCompositProperties[node.Property] = composite; composite.PropertyList.AddLast(node.Property); var current = node; while (current.Children.Count == 1 && !current.IsFinal) { var next = current.Children.First(); if (next.IsRoot || next.Parents.Count > 1 || cache.AllCompositProperties.ContainsKey(next.Property)) { break; } current = next; composite.PropertyList.AddLast(current.Property); } foreach (var listNode in current.Children) { composite.Children.AddLast(OptimizeNode(listNode, cache)); } return(composite); }
public HashSet <PropertyInfoVertex> BuildSearchTree( TypeVertex currentVertex, TypeVertex searchVertex, PathBuilderSearchCache cache) { var properties = new HashSet <PropertyInfoVertex>(); HashSet <PropertyInfoVertex> cachedProperties; if (cache.AllVertices.TryGetValue(currentVertex, out cachedProperties)) { return(cachedProperties); } cache.AllVertices[currentVertex] = properties; var allEdges = new LinkedList <PropertyEdge>(); allEdges.AddRange(currentVertex.Children); currentVertex.Casts.ForEach( castEdge => { if (!_typeGraph.PathExists(castEdge.Value.CastTo, searchVertex)) { return; } allEdges.AddRange(castEdge.Value.CastTo.Children); }); allEdges.ForEach( searchNode => { var childVertex = searchNode.Value.Child; var propertyInfo = searchNode.Value.PropertyInfo; if (!_typeGraph.PathExists(childVertex, searchVertex)) { return; } PropertyInfoVertex rootProperty; if (!cache.AllProperties.TryGetValue(propertyInfo, out rootProperty)) { rootProperty = new PropertyInfoVertex(propertyInfo); cache.AllProperties[propertyInfo] = rootProperty; } properties.Add(rootProperty); }); allEdges.ForEach( searchNode => { var childVertex = searchNode.Value.Child; var propertyInfo = searchNode.Value.PropertyInfo; PropertyInfoVertex rootProperty; if (!cache.AllProperties.TryGetValue(propertyInfo, out rootProperty)) { return; } var childProperties = BuildSearchTree(childVertex, searchVertex, cache); rootProperty.Children.UnionWith(childProperties); foreach (var childProperty in childProperties) { childProperty.Parents.Add(rootProperty); } }); return(properties); }