TStr TNodeJsFPath::GetCanonicalPath(const TStr& FPath) { // Get absolute path TStr AbsFPath = TStr::GetNrAbsFPath(FPath); // Remove any redundancies TStrV CanonV; AbsFPath.SplitOnAllCh('/', CanonV); TSStack<TStr> CanonS; TStr CurrStr; for (int ElN = 0; ElN < CanonV.Len(); ++ElN) { CurrStr = CanonV.GetVal(ElN); if (CurrStr == "..") { EAssertR(!CanonS.Empty(), "Stack empty"); CanonS.Pop(); } else if (CurrStr != ".") { CanonS.Push(CurrStr+"/"); } } // Assemble the canonical path (from left to right EAssertR(!CanonS.Empty(), "Stack empty"); // We start with drive letter (Windows) or slash (Unix) TChA CanonFPath = AbsFPath.LeftOf('/'); CanonFPath += '/'; // Get the rest of the path for (int CanonN = CanonS.Len() - 1; CanonN >= 0; CanonN--) { CanonFPath += CanonS[CanonN]; } // Done return CanonFPath; }
void TGraphCascade::TopologicalSort(TIntV& SortedNIdV) { int Nodes = Graph.GetNodes(); SortedNIdV.Gen(Nodes, 0); // result THash<TInt, TBool> Marks(Nodes); // nodeid -> mark map THash<TInt,TBool> TempMarks(Nodes); // nodeid -> temp mark map THash<TInt, TBool> Added(Nodes); TIntV NIdV; Graph.GetNIdV(NIdV); // all node ids // set marks for (int NodeN = 0; NodeN < Nodes; NodeN++) { int NodeId = NIdV[NodeN]; Marks.AddDat(NodeId, false); TempMarks.AddDat(NodeId, false); Added.AddDat(NodeId, false); } TSStack<TInt> Stack; for (int NodeN = 0; NodeN < Nodes; NodeN++) { int NodeId = NIdV[NodeN]; // select an unmarked node if (!Marks.GetDat(NodeId)) { Stack.Push(NodeId); while (!Stack.Empty()) { // visit TopNode int TopNodeId = Stack.Top(); Marks.GetDat(TopNodeId) = true; TempMarks.GetDat(TopNodeId) = true; // add children, set their temp marks to true TNGraph::TNodeI NI = Graph.GetNI(TopNodeId); int Children = NI.GetOutDeg(); bool IsFinal = true; for (int ChildN = 0; ChildN < Children; ChildN++) { int ChildId = NI.GetOutNId(ChildN); EAssertR(!TempMarks.GetDat(ChildId), "TGraphCascade::TopologicalSort: the graph is not a DAG!"); if (!Marks.GetDat(ChildId)) { // unvisited node IsFinal = false; Stack.Push(ChildId); } } if (IsFinal) { // push TopNode to tail if (!Added.GetDat(TopNodeId)) { SortedNIdV.Add(TopNodeId); Added.GetDat(TopNodeId) = true; } TempMarks.GetDat(TopNodeId) = false; Stack.Pop(); } } } } SortedNIdV.Reverse(); }