Beispiel #1
0
        private bool FindCycle(IDependencyVertex root, IDependencyVertex next, ref ArrayList members, ref Stack stack)
        {
            if (s_diagnostics_StackCheck)
            {
                if (stack.Contains(next))
                {
                    string            msg    = "GraphSequencer has detected a dependency cycle in the initialization sequence of this model.\r\n";
                    IDependencyVertex thisDv = next;
                    int depct = 1;
                    foreach (IDependencyVertex idv in (object[])stack.ToArray())
                    {
                        msg   += string.Format("{0}.) {1} depends on {2}.\r\n", (depct++), thisDv, idv);
                        thisDv = idv;
                    }
                    throw new ApplicationException(msg);
                }
                else
                {
                    stack.Push(next);
                }
            }

            foreach (IDependencyVertex parent in next.PredecessorList)
            {
                if (parent.Equals(root) || FindCycle(root, parent, ref members, ref stack))
                {
                    members.Add(next);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #2
0
 /// <summary>
 /// Call this with an IDependencyVertex object to add it to the sequencer
 /// for consideration next time there is a request for a service sequence list.
 /// </summary>
 /// <param name="vertex">An IDependencyVertex object</param>
 public void AddVertex(IDependencyVertex vertex)
 {
     m_serviceSequenceList = null;
     if (m_vertices.Contains(vertex))
     {
         string msg = string.Format("Dependency sequencer error: Attempt to register a dependency vertex, {0}, that already exists in the list.",
                                    vertex);
         throw new ApplicationException(msg);
     }
     m_vertices.Add((IDependencyVertex)vertex);
 }
Beispiel #3
0
        /// <summary>
        /// Recalculates the service sequence.
        /// </summary>
        protected void RecalculateServiceSequence()
        {
            m_serviceSequenceList = new ArrayList();

            // First we create the list of vertex data and a hashtable to find
            // the vertex from the underlying.
            ArrayList lstVerts = new ArrayList();
            Hashtable htVerts  = new Hashtable();

            //_Debug.WriteLine("Calculating Service Sequence.");
            foreach (IDependencyVertex idv in m_vertices)
            {
                VertexRecord v = new VertexRecord(idv);

                if (s_diagnostics)
                {
                    _Debug.WriteLine("Parents of " + v.Underlying);
                    foreach (IDependencyVertex idv2 in v.Underlying.PredecessorList)
                    {
                        _Debug.WriteLine("\t" + idv2);
                    }
                }

                lstVerts.Add(v);
                htVerts.Add(idv, v);
                if (s_diagnostics)
                {
                    _Debug.WriteLine(String.Format("New vertex, {0} with {1} dependents.", idv, idv.PredecessorList.Count));
                }
            }

            // Each underlying knows who it depends on - we need each vertex to
            // know, rather, who depends on IT.
            foreach (VertexRecord v in lstVerts)
            {
                v.EstablishChildRelationships(htVerts);
            }

            try {
                bool bResortNeeded             = true;
                int  numAffectedLastAdjustment = lstVerts.Count;
                // We will repeat the following until all nodes have been evaluated.
                while (lstVerts.Count > 0)
                {
                    //if ( lstVerts.Count%100 == 0 ) Console.WriteLine("%%%" + lstVerts.Count);

                    // Sort remaining vertices by the provided Comparer. (defaults to
                    // sorting first by nOrder, then by the vertices' provided comparator.
                    // See below for an explanation of the 'bResortNeeded' boolean.
                    if (bResortNeeded)
                    {
                        if (numAffectedLastAdjustment > lstVerts.Count * 0.02)
                        {
                            lstVerts.Sort(GetVertexComparer());
                        }
                        else
                        {
                            lstVerts = BubbleSort(lstVerts);
                        }
                    }

                    // Dumps the sort order as it progresses...
                    //foreach ( Vertex v in lstVerts ) _Debug.WriteLine(v.Underlying + " : " + v.Order);

                    // Move the least vertex to the ServiceOrder list.
                    VertexRecord next = (VertexRecord)lstVerts[0];
                    lstVerts.RemoveAt(0);
                    m_serviceSequenceList.Add(next.Underlying);

                    // If the vertex we just removed had no parents, then the sort order
                    // that was valid in the preceding step is still valid. Nobody had
                    // their child-count reduced, so no one's position in the sort will
                    // have had a reason to change. We just move on to the next one...
                    numAffectedLastAdjustment = next.Underlying.PredecessorList.Count;
                    bResortNeeded             = (numAffectedLastAdjustment > 0);

                    if (next.Order != 0)
                    {
                        IDependencyVertex root    = next.Underlying;
                        ArrayList         members = new ArrayList();
                        members.Add(root);
                        Stack stack = new Stack();
                        foreach (IDependencyVertex parent in root.PredecessorList)
                        {
                            if (!FindCycle(root, parent, ref members, ref stack))
                            {
                                break;
                            }
                        }
                        throw new GraphCycleException(members);
                    }

                    // Decrement the Order of all vertices that this one depended on.
                    next.DecrementParentsChildCount(htVerts);
                }
            } catch (StackOverflowException soe) {
                throw new ApplicationException("The GraphSequencer has detected a probable dependency cycle in the initialization sequence of this model. For details, set the GraphSequencer.StackCheck key to true in the modeler's app.config file.", soe);
            }

            #region Diagnostics

            if (s_diagnostics)
            {
                _Debug.WriteLine("Dependency Solver determines sequence to be:");
                foreach (IDependencyVertex idv in m_serviceSequenceList)
                {
                    _Debug.WriteLine("\t" + idv);
                }
            }

            #endregion Diagnostics
        }
Beispiel #4
0
 public VertexRecord(IDependencyVertex underlying)
 {
     m_underlying = underlying;
     m_order      = 0;
 }