// 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); }