示例#1
0
        // It returns -2 of obj is a dead end
        // Returns n >= 0, if all paths starting at 'obj' end in objects already
        // visited. 'n' is the index of a node in rootInfo.Path, which is the closest
        // visited node found
        // Returns -1 otherwise.
        // This return value is used to detect dead ends.

        int FindRoot(RootInfo rootInfo, PathTree pathTree, int obj)
        {
            if (rootInfo.DeadEnds.ContainsKey(obj))
            {
                return(-2);
            }

            int curval;

            if (rootInfo.Visited.TryGetValue(obj, out curval))
            {
                // The object has already been visited
                if (rootInfo.Path.Count >= curval)
                {
                    return(rootInfo.Path.IndexOf(obj));
                }
            }
            rootInfo.Visited [obj] = rootInfo.Path.Count;

            int treePos = pathTree.GetObjectNode(obj);

            if (treePos != -1)
            {
                // If this object already has partial paths to roots,
                // reuse them.
                FindTreeRoot(rootInfo.Path, rootInfo.Roots, pathTree, treePos);
                return(-1);
            }

            rootInfo.Path.Add(obj);

            bool hasrefs    = false;
            int  findresult = int.MaxValue;

            foreach (int oref in GetReferencers(obj))
            {
                hasrefs = true;
                if (!rootInfo.BaseObjects.ContainsKey(oref))
                {
                    int fr = FindRoot(rootInfo, pathTree, oref);
                    if (fr != -2 && fr < findresult)
                    {
                        findresult = fr;
                    }
                }
            }

            if (!hasrefs)
            {
                // A root
                rootInfo.Visited.Remove(obj);
                RegisterPath(rootInfo.Roots, rootInfo.Path, obj);
                findresult = -1;
            }

            rootInfo.Path.RemoveAt(rootInfo.Path.Count - 1);

            // If all children paths end in nodes already visited, it means that it is a dead end.
            if (findresult >= rootInfo.Path.Count)
            {
                rootInfo.DeadEnds [obj] = obj;
//				Console.WriteLine ("de: " + findresult);
            }

            return(findresult);
        }