示例#1
0
文件: DAG.cs 项目: rzel/Aleph
        /// <summary>
        /// Add a graph node and all of its ancestors to the DAG.
        /// Returns TRUE iff the node and all of its ancestors were successfully added.
        /// Note that even in the case of a false return value, there could have been some additions to the DAG.
        /// We do guarantee that after this operation, the DAG will be consistent, in the sense that a GraphNode being in the DAG guarantees that its ancestors are also.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Add(IGraphNode <NodeDataType> item)
        {
            if (this.Contains(item))
            {
                return(true);      // If the node is already in this DAG, then there's nothing to do.
            }
            OnDagChange?.Invoke(); // In case someone has subscribed to the changed DAG event.  Because of recursion, this event will be thrown a lot, but that shouldn't be a problem

            if (item is RootNode <NodeDataType> )
            {
                return(_containedNodes.Add(item)); // Adding a root node takes no work at all
            }
            if (item is GraphNode <NodeDataType> )
            {
                bool returnVal = true;
                IEnumerable <IGraphNode <NodeDataType> > parentNodes = (item as GraphNode <NodeDataType>).ParentNodes;
                foreach (IGraphNode <NodeDataType> parent in parentNodes) // We want this to throw an error if parentNodes is null, since that shouldn't be able to ever happen
                {
                    if (!this.Add(parent))
                    {
                        returnVal = false;
                    }
                }

                if (returnVal)
                {
                    return(_containedNodes.Add(item));
                }
                return(false); // If we failed to add some ancestor, then we should NOT add this item.
            }

            throw new NotImplementedException(); // We should never reach this point!
        }
示例#2
0
文件: DAG.cs 项目: rzel/Aleph
        /// <summary>
        /// Remove a graph node and all of its descendants from the DAG.
        /// This returns TRUE iff the node and all of its descendants were removed from the DAG.
        /// In the case of a false return, its possible that only some of the nodes were removed.
        /// We do guarantee that after this operation, the DAG will be consistent, in the sense that a Node being in the DAG guarantees that its ancestors are also.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Remove(IGraphNode <NodeDataType> item)
        {
            if (!this.Contains(item))
            {
                return(true);      // If the item isn't in the DAG, then we're done.
            }
            OnDagChange?.Invoke(); // In case someone has subscribed to the changed DAG event

            IEnumerable <IGraphNode <NodeDataType> > childNodes = item.ChildNodes;
            bool returnVal = true;

            if (childNodes != null)
            {
                foreach (IGraphNode <NodeDataType> child in childNodes)
                {
                    if (!this.Remove(child))
                    {
                        returnVal = false;
                    }
                }
            }

            if (returnVal)
            {
                return(_containedNodes.Remove(item));
            }
            return(false); // We failed to remove some descendant, so we should NOT remove this item.
        }
示例#3
0
文件: DAG.cs 项目: rzel/Aleph
 public void Clear()
 {
     OnDagChange?.Invoke(); // In case someone has subscribed to the changed DAG event
     _containedNodes.Clear();
 }
示例#4
0
文件: DAG.cs 项目: rzel/Aleph
 /// <summary>
 /// Takes the intersection of two DAGs.
 /// This will act like a typical intersection of sets, because both DAGs being intersected are initially consistent.
 /// </summary>
 /// <param name="otherDAG"></param>
 public void IntersectWith(DAG <NodeDataType> otherDAG)
 {
     OnDagChange?.Invoke();                                        // In case someone has subscribed to the changed DAG event.  Note that this will fire even if this DAG is unchanged by the intersection.
     this._containedNodes.IntersectWith(otherDAG._containedNodes); // This assumes that both DAGs are "consistent" in the sense that a node is in a consistent DAG only if all of that node's parents are in the DAG
 }