コード例 #1
0
        private void RemoveUnsatisfiedSuccessorActivity(T activityId)
        {
            // Check to make sure the node really exists.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return;
            }

            if (node.NodeType == NodeType.End ||
                node.NodeType == NodeType.Normal)
            {
                // If the activity was an unsatisfied successor, then remove it from the lookup.
                IList <KeyValuePair <T, HashSet <Node <T, TActivity> > > > kvps =
                    UnsatisfiedSuccessorsLookup.Where(x => x.Value.Select(y => y.Id).Contains(activityId)).ToList();

                foreach (KeyValuePair <T, HashSet <Node <T, TActivity> > > kvp in kvps)
                {
                    HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes = kvp.Value;
                    unsatisfiedSuccessorNodes.RemoveWhere(x => x.Id.Equals(activityId));
                    if (!unsatisfiedSuccessorNodes.Any())
                    {
                        UnsatisfiedSuccessorsLookup.Remove(kvp);
                    }
                }
            }
        }
コード例 #2
0
        private void ResolveUnsatisfiedSuccessorActivities(T activityId)
        {
            // Check to make sure the node really exists.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> dependencyNode))
            {
                return;
            }

            // Check to see if any existing activities were expecting this activity
            // as a dependency. If so, then then hook their nodes to this activity with an edge.
            if (UnsatisfiedSuccessorsLookup.TryGetValue(activityId, out HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes))
            {
                // If the dependency node is an End or Isolated node, then convert it.
                if (dependencyNode.NodeType == NodeType.End)
                {
                    dependencyNode.SetNodeType(NodeType.Normal);
                }
                else if (dependencyNode.NodeType == NodeType.Isolated)
                {
                    dependencyNode.SetNodeType(NodeType.Start);
                }

                foreach (Node <T, TActivity> successorNode in unsatisfiedSuccessorNodes)
                {
                    T   edgeId = EdgeIdGenerator();
                    var edge   = new Edge <T, TEvent>(EventGenerator(edgeId));
                    dependencyNode.OutgoingEdges.Add(edgeId);
                    EdgeTailNodeLookup.Add(edgeId, dependencyNode);
                    successorNode.IncomingEdges.Add(edgeId);
                    EdgeHeadNodeLookup.Add(edgeId, successorNode);
                    EdgeLookup.Add(edgeId, edge);
                }
                UnsatisfiedSuccessorsLookup.Remove(activityId);
            }
        }
コード例 #3
0
 public virtual void Reset()
 {
     EdgeLookup.Clear();
     NodeLookup.Clear();
     UnsatisfiedSuccessorsLookup.Clear();
     EdgeHeadNodeLookup.Clear();
     EdgeTailNodeLookup.Clear();
 }
コード例 #4
0
        private void ResolveUnsatisfiedSuccessorActivities(T activityId)
        {
            // Check to make sure the edge really exists.
            if (!EdgeLookup.ContainsKey(activityId))
            {
                return;
            }
            // Check to see if any existing activities were expecting this activity
            // as a dependency. If so, then then hook up their tail nodes to this
            // activity's head node with a dummy edge.
            if (UnsatisfiedSuccessorsLookup.TryGetValue(activityId, out HashSet <Node <T, TEvent> > unsatisfiedSuccessorTailNodes))
            {
                // We know that there are unsatisfied dependencies, so create a head node.
                T   headEventId = NodeIdGenerator();
                var headNode    = new Node <T, TEvent>(EventGenerator(headEventId));
                headNode.IncomingEdges.Add(activityId);
                EdgeHeadNodeLookup.Add(activityId, headNode);
                NodeLookup.Add(headNode.Id, headNode);

                foreach (Node <T, TEvent> tailNode in unsatisfiedSuccessorTailNodes)
                {
                    T   dummyEdgeId = EdgeIdGenerator();
                    var dummyEdge   = new Edge <T, TActivity>(DummyActivityGenerator(dummyEdgeId));
                    tailNode.IncomingEdges.Add(dummyEdgeId);
                    EdgeHeadNodeLookup.Add(dummyEdgeId, tailNode);
                    headNode.OutgoingEdges.Add(dummyEdgeId);
                    EdgeTailNodeLookup.Add(dummyEdgeId, headNode);
                    EdgeLookup.Add(dummyEdge.Id, dummyEdge);
                }
                UnsatisfiedSuccessorsLookup.Remove(activityId);
            }
            else
            {
                // No existing activities were expecting this activity as a dependency,
                // so attach it directly to the end node via a dummy.
                T headEventId = NodeIdGenerator();
                Node <T, TEvent> dependencyHeadNode = new Node <T, TEvent>(EventGenerator(headEventId));

                dependencyHeadNode.IncomingEdges.Add(activityId);
                EdgeHeadNodeLookup.Add(activityId, dependencyHeadNode);
                NodeLookup.Add(dependencyHeadNode.Id, dependencyHeadNode);

                T   dummyEdgeId = EdgeIdGenerator();
                var dummyEdge   = new Edge <T, TActivity>(DummyActivityGenerator(dummyEdgeId));

                dependencyHeadNode.OutgoingEdges.Add(dummyEdgeId);
                EdgeTailNodeLookup.Add(dummyEdgeId, dependencyHeadNode);
                EdgeLookup.Add(dummyEdgeId, dummyEdge);

                EndNode.IncomingEdges.Add(dummyEdgeId);
                EdgeHeadNodeLookup.Add(dummyEdgeId, EndNode);
            }
        }
コード例 #5
0
        private void RemoveUnsatisfiedSuccessorActivityDependencies(T activityId, HashSet <T> dependencies)
        {
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }

            // If the activity was an unsatisfied successor for these dependencies,
            // then remove them from the lookup.
            foreach (T dependencyId in dependencies)
            {
                if (UnsatisfiedSuccessorsLookup.TryGetValue(dependencyId, out HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes))
                {
                    unsatisfiedSuccessorNodes.RemoveWhere(x => x.Id.Equals(activityId));
                    if (!unsatisfiedSuccessorNodes.Any())
                    {
                        UnsatisfiedSuccessorsLookup.Remove(dependencyId);
                    }
                }
            }
        }
コード例 #6
0
        public override bool AddActivity(TActivity activity, HashSet <T> dependencies)
        {
            if (activity == null)
            {
                throw new ArgumentNullException(nameof(activity));
            }
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }
            if (EdgeLookup.ContainsKey(activity.Id))
            {
                return(false);
            }
            if (dependencies.Contains(activity.Id))
            {
                return(false);
            }
            // Create a new edge for the activity.
            var edge = new Edge <T, TActivity>(activity);

            EdgeLookup.Add(edge.Id, edge);

            // We expect dependencies at some point.
            if (dependencies.Any())
            {
                // Since we use dummy edges to connect all tail nodes, we can create
                // a new tail node for this edge.
                T   tailEventId = NodeIdGenerator();
                var tailNode    = new Node <T, TEvent>(EventGenerator(tailEventId));
                tailNode.OutgoingEdges.Add(edge.Id);
                EdgeTailNodeLookup.Add(edge.Id, tailNode);
                NodeLookup.Add(tailNode.Id, tailNode);

                // Check which of the expected dependencies currently exist.
                IList <T> existingDependencies    = EdgeLookup.Keys.Intersect(dependencies).ToList();
                IList <T> nonExistingDependencies = dependencies.Except(existingDependencies).ToList();

                // If any expected dependencies currently exist, then hook up their head
                // node to this edge's tail node with dummy edges.
                foreach (T dependencyId in existingDependencies)
                {
                    Node <T, TEvent> dependencyHeadNode = EdgeHeadNodeLookup[dependencyId];
                    T   dummyEdgeId = EdgeIdGenerator();
                    var dummyEdge   = new Edge <T, TActivity>(DummyActivityGenerator(dummyEdgeId));
                    tailNode.IncomingEdges.Add(dummyEdgeId);
                    EdgeHeadNodeLookup.Add(dummyEdgeId, tailNode);

                    // If the head node of the dependency is the End node, then convert it.
                    if (dependencyHeadNode.NodeType == NodeType.End)
                    {
                        dependencyHeadNode.SetNodeType(NodeType.Normal);
                    }

                    dependencyHeadNode.OutgoingEdges.Add(dummyEdgeId);
                    EdgeTailNodeLookup.Add(dummyEdgeId, dependencyHeadNode);
                    EdgeLookup.Add(dummyEdgeId, dummyEdge);
                }

                // If any expected dependencies currently do not exist, then record their
                // IDs and add this edge's tail node as an unsatisfied successor.
                foreach (T dependencyId in nonExistingDependencies)
                {
                    if (!UnsatisfiedSuccessorsLookup.TryGetValue(dependencyId, out HashSet <Node <T, TEvent> > tailNodes))
                    {
                        tailNodes = new HashSet <Node <T, TEvent> >();
                        UnsatisfiedSuccessorsLookup.Add(dependencyId, tailNodes);
                    }
                    tailNodes.Add(tailNode);
                }
            }
            else
            {
                // No dependencies, so attach it directly to the start node.
                StartNode.OutgoingEdges.Add(edge.Id);
                EdgeTailNodeLookup.Add(edge.Id, StartNode);
            }
            ResolveUnsatisfiedSuccessorActivities(edge.Id);
            return(true);
        }
コード例 #7
0
        public override bool AddActivityDependencies(T activityId, HashSet <T> dependencies)
        {
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }

            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!dependencies.Any())
            {
                return(true);
            }
            if (dependencies.Contains(activityId))
            {
                return(false);
            }

            // If the node is an Start or Isolated node, then convert it.
            if (node.NodeType == NodeType.Start)
            {
                node.SetNodeType(NodeType.Normal);
            }
            else if (node.NodeType == NodeType.Isolated)
            {
                node.SetNodeType(NodeType.End);
            }

            // Check which of the expected dependencies currently exist.
            IList <T> existingDependencies    = NodeLookup.Keys.Intersect(dependencies).ToList();
            IList <T> nonExistingDependencies = dependencies.Except(existingDependencies).ToList();

            // If any expected dependencies currently exist, generate an edge to connect them.
            foreach (T dependencyId in existingDependencies)
            {
                Node <T, TActivity> dependencyNode = NodeLookup[dependencyId];
                T   edgeId = EdgeIdGenerator();
                var edge   = new Edge <T, TEvent>(EventGenerator(edgeId));
                node.IncomingEdges.Add(edgeId);
                EdgeHeadNodeLookup.Add(edgeId, node);

                // If the dependency node is an End or Isolated node, then convert it.
                if (dependencyNode.NodeType == NodeType.End)
                {
                    dependencyNode.SetNodeType(NodeType.Normal);
                }
                else if (dependencyNode.NodeType == NodeType.Isolated)
                {
                    dependencyNode.SetNodeType(NodeType.Start);
                }

                dependencyNode.OutgoingEdges.Add(edgeId);
                EdgeTailNodeLookup.Add(edgeId, dependencyNode);
                EdgeLookup.Add(edgeId, edge);
            }

            // If any expected dependencies currently do not exist, then record their
            // IDs and add this node as an unsatisfied successor.
            foreach (T dependencyId in nonExistingDependencies)
            {
                if (!UnsatisfiedSuccessorsLookup.TryGetValue(dependencyId, out HashSet <Node <T, TActivity> > successorNodes))
                {
                    successorNodes = new HashSet <Node <T, TActivity> >();
                    UnsatisfiedSuccessorsLookup.Add(dependencyId, successorNodes);
                }
                successorNodes.Add(node);
            }
            return(true);
        }