/// <summary>
        /// Gets all sub paths like path[1..n], path[2..n], path[3..n] to path[n-1..n]
        /// </summary>
        /// <param name="maxTrim">maximum amount to trim by, inclusive</param>
        /// <returns>enumerable of sub-paths</returns>
        public IEnumerable <CodePath> GetSubPaths(int maxTrim = -1)
        {
            var current = this.GetNextNode(this.FirstNode);
            var trimmed = 1;

            while (current != null)
            {
                var newCodePath = new CodePath();
                newCodePath.FirstNode = current;
                newCodePath.LastNode  = this.LastNode;
                newCodePath.treePath  = new Dictionary <ulong, int>(this.treePath);
                newCodePath.Length    = this.Length - trimmed;
                yield return(newCodePath);

                if (current == this.LastNode)
                {
                    yield break;
                }

                current = this.GetNextNode(current);
                if (trimmed++ == maxTrim && maxTrim > 0)
                {
                    yield break;
                }
            }
        }
        public CodePath ConcatNew(CodePath other)
        {
            if (this.LastNode.NodeId == other.FirstNode.NodeId)
            {
                return(this);
            }

            var newPath = new CodePath();

            newPath.FirstNode = this.FirstNode;
            var version = this.LastNode.AddNextNode(other.FirstNode);

            newPath.treePath = new Dictionary <ulong, int>(this.treePath);

            foreach (var kv in other.treePath)
            {
                if (!newPath.treePath.ContainsKey(kv.Key))
                {
                    newPath.treePath[kv.Key] = kv.Value;
                }
            }

            newPath.treePath[this.LastNode.NodeId] = version;

            newPath.LastNode = other.LastNode;
            newPath.Length   = this.Length + other.Length;
            return(newPath);
        }
        /// <summary>
        /// Creates a code path with a single method
        /// </summary>
        /// <param name="method">method to add</param>
        /// <returns>initialized code path</returns>
        public static CodePath FromSingleMethod(Method method)
        {
            var node = new MethodNode(method);
            var path = new CodePath
            {
                FirstNode = node,
                LastNode  = node
            };

            path.Length = 1;

            return(path);
        }
        public CodePath Concat(CodePath other)
        {
            if (this.LastNode.NodeId == other.FirstNode.NodeId)
            {
                return(this);
            }

            var version = this.LastNode.AddNextNode(other.FirstNode);

            this.treePath[this.LastNode.NodeId] = version;

            this.LastNode = other.LastNode;
            this.Length  += other.Length;
            return(this);
        }
Exemple #5
0
        /// <summary>
        /// Constructs the partial paths which forms the sub-graph of solution nodes
        /// </summary>
        /// <param name="start">starting method</param>
        /// <param name="end">ending method</param>
        /// <param name="cancellationToken">cancellation token</param>
        /// <returns>void Task</returns>
        public async Task ConstructPartialPaths(Method start,
                                                Method end,
                                                CancellationToken cancellationToken)
        {
            this.partialPaths     = new List <CodePath>();
            this.visited          = new HashSet <Method>();
            this.pathSolutionMap  = new Dictionary <Method, List <CodePath> >();
            this.solutionMethods  = new HashSet <Method>();
            this.completedMethods = new HashSet <Method>();

            // left for potential future multi-threading support
            var proctor = new StackProctor(1);
            var stack   = proctor.GetStack(0);

            stack.Push(CodePath.FromSingleMethod(start));

            await Task.Run(() => RunSearchThread(end, proctor, 0, cancellationToken));
        }
        /// <summary>
        /// Compare the sort order for the two classes
        /// </summary>
        /// <param name="other">the class to compare to </param>
        /// <returns>0 for equal, -1 for other greater, 1 for this greater</returns>
        public int CompareTo(CodePath other)
        {
            var stringKeyBuilder1 = new StringBuilder();
            var stringKeyBuilder2 = new StringBuilder();

            foreach (var method in this)
            {
                stringKeyBuilder1.Append(method.FullName);
            }

            foreach (var method in other)
            {
                stringKeyBuilder2.Append(method.FullName);
            }

            var stringKey1 = stringKeyBuilder1.ToString();
            var stringKey2 = stringKeyBuilder2.ToString();

            return(stringKey1.CompareTo(stringKey2));
        }
        /// <summary>
        /// Adds a method to the end of this code path and returns new CodePath.
        /// Leaves the current instance unmodified
        /// </summary>
        /// <param name="node">method to add</param>
        /// <returns>cloned code path with new method added</returns>
        public CodePath AddLastNew(Method method)
        {
            if (this.FirstNode == null && this.LastNode == null)
            {
                return(FromSingleMethod(method));
            }

            var @new    = new CodePath();
            var newNode = new MethodNode(method);

            @new.FirstNode = this.FirstNode;
            var version = this.LastNode.AddNextNode(newNode);

            @new.treePath = new Dictionary <ulong, int>(this.treePath);
            @new.treePath[this.LastNode.NodeId] = version;

            @new.LastNode = newNode;
            @new.Length   = this.Length + 1;

            return(@new);
        }
Exemple #8
0
        /// <summary>
        /// The <see cref="path" /> parameter must end in either a goal method,
        /// or a known intermediate method. For each subsequence ending in the same
        /// method, add the beginning node to known solution nodes
        /// </summary>
        /// <param name="path">the path, and whose subpaths, to cache</param>
        private void AddPathToSolutionMap(CodePath path)
        {
            Method method = null;

            foreach (var subPath in path.GetSubPaths())
            {
                if (method != null)
                {
                    if (!pathSolutionMap.ContainsKey(method))
                    {
                        pathSolutionMap[method] = new List <CodePath>();
                    }

                    if (!pathSolutionMap[method].Contains(subPath))
                    {
                        pathSolutionMap[method].Add(subPath);
                    }
                    solutionMethods.Add(method);
                }

                method = subPath.FirstMethod;
            }
        }