예제 #1
0
        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);
        }
예제 #2
0
        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);
        }