Example #1
0
        public static LinkedList <CompositPropertyVertex> OptimizePaths(HashSet <PropertyInfoVertex> propertyPaths,
                                                                        PathBuilderSearchCache cache)
        {
            var optimizePaths = new LinkedList <CompositPropertyVertex>();

            foreach (var node in propertyPaths)
            {
                optimizePaths.AddLast(OptimizeNode(node, cache));
            }

            return(optimizePaths);
        }
Example #2
0
        public LinkedList <CompositPropertyVertex> Find(TBaseSearchInterface source, Type searchType)
        {
            var sourceType = source.GetType();
            var key        = Tuple.Create(sourceType, searchType);

            var cachedResult = _cache.GetOrAdd(
                key,
                tuple =>
            {
                var newCachedResult            = new PathBuilderSearchCache(sourceType, searchType);
                var sourceTypes                = SearchHelper <TBaseSearchInterface> .FindLeafInterfaces(sourceType);
                var paths                      = GetOrBuildPaths(sourceTypes, searchType, newCachedResult);
                var optimized                  = OptimizePaths(paths, newCachedResult);
                newCachedResult.OptimizedPaths = optimized;

                return(newCachedResult);
            });

            return(cachedResult.OptimizedPaths);
        }
Example #3
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);
        }
Example #4
0
        public HashSet <PropertyInfoVertex> GetOrBuildPaths(IEnumerable <Type> sourceTypes, Type searchType,
                                                            PathBuilderSearchCache cache)
        {
            var propertyPathsSet = new HashSet <PropertyInfoVertex>();
            var searchVertex     = _typeGraph.GetTypeVertex(searchType);

            foreach (var sourceType in sourceTypes)
            {
                var sourceVertex = _typeGraph.GetTypeVertex(sourceType);

                if (cache.AllVertices.ContainsKey(sourceVertex))
                {
                    propertyPathsSet.UnionWith(cache.AllVertices[sourceVertex]);
                    continue;
                }

                if (!_typeGraph.PathExists(sourceVertex, searchVertex))
                {
                    continue;
                }

                var properties = BuildSearchTree(sourceVertex, searchVertex, cache);

                if (properties.Count == 0)
                {
                    throw new InvalidOperationException("Не найден ни один путь");
                }

                propertyPathsSet.UnionWith(properties);
            }

            if (propertyPathsSet.Count == 0)
            {
                throw new InvalidOperationException("Не найден ни один путь");
            }

            foreach (var node in propertyPathsSet)
            {
                node.IsRoot = true;
            }

            var hierarchyTypes = SearchHelper <TBaseSearchInterface> .FindHierarchy(searchType);

            foreach (var type in hierarchyTypes)
            {
                var typeVertex = _typeGraph.GetTypeVertex(type);
                HashSet <PropertyInfoVertex> edges;

                if (!cache.AllVertices.TryGetValue(typeVertex, out edges))
                {
                    continue;
                }

                foreach (var parent in edges.SelectMany(edge => edge.Parents))
                {
                    parent.IsFinal = true;
                }
            }

            return(propertyPathsSet);
        }
Example #5
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);
        }