コード例 #1
0
        private void SealNodeForBulkIncomingEdgeAddition(NodeId target)
        {
            BufferPointer <NodeEdgeListHeader> targetInEdges = InEdges.GetBufferPointer(target.Value);

            targetInEdges.Buffer[targetInEdges.Index].Seal();
            Contract.Assert(targetInEdges.Buffer[targetInEdges.Index].IsSealed, "Node should be sealed");
        }
コード例 #2
0
        private void AddEdges(NodeId target, HashSet <Edge> incomingEdges)
        {
            BufferPointer <NodeEdgeListHeader> targetInEdges = InEdges.GetBufferPointer(target.Value);

            Contract.Assert(targetInEdges.Buffer[targetInEdges.Index].IsSealed, "Bulk additions can only be made to sealed nodes");

            using (m_globalLock.AcquireReadLock())
            {
                Contract.Assert(m_state == MutableGraphState.Mutating, "Graph mutations are not permitted after sealing");

                foreach (var incoming in incomingEdges)
                {
                    var source       = incoming.OtherNode;
                    var incomingLock = m_locks[GetLockNumber(source.Value)];
                    using (AcquireLockForState(incomingLock, MutableGraphState.Mutating))
                    {
                        // AddEdgeUnchecked is thread-safe with respect to concurrent modifications
                        AddEdgeUnchecked(
                            source: source,
                            target: target,
                            targetInEdges: targetInEdges,
                            isLight: incoming.IsLight,
                            bulkAddingTargetIncoming: true);
                    }
                }

                Interlocked.Increment(ref m_modificationsSinceLastNodeHeightComputation);
            }
        }
コード例 #3
0
ファイル: StructureNode.cs プロジェクト: mmyydd/reko
 // Add an edge from src to this node if it doesn't already exist. NB: only interval
 // nodes need this routine as the in edges for normal nodes are built in SetLoopStamps
 public void AddEdgeFrom(StructureNode src)
 {
     if (!InEdges.Contains(src))
     {
         InEdges.Add(src);
     }
 }
コード例 #4
0
 public void Delete()
 {
     if (!isDirected)     // irányított
     {
         for (int i = 0; i < Edges.Count;)
         {
             Edge temp = Edges[i];
             Edges.RemoveAt(i);
             temp.DeleteEdge();
             EdgeAdded();
         }
     }
     else     // nem irányított
     {
         for (int i = 0; i < InEdges.Count;)
         {
             Edge temp = InEdges[i];
             InEdges.RemoveAt(i);
             temp.DeleteEdge();
             EdgeAdded();
         }
         for (int i = 0; i < OutEdges.Count;)
         {
             Edge temp = OutEdges[i];
             OutEdges.RemoveAt(i);
             temp.DeleteEdge();
             EdgeAdded();
         }
     }
     this.parent.Children.Remove(this);
     this.Visibility = System.Windows.Visibility.Hidden;
 }
コード例 #5
0
ファイル: VisibilityVertex.cs プロジェクト: Caliper/MSAGL
 internal void RemoveInEdge(VisibilityEdge edge)
 {
     for (int ii = InEdges.Count - 1; ii >= 0; --ii)
     {
         if (InEdges[ii] == edge)
         {
             InEdges.RemoveAt(ii);
             break;
         }
     }
 }
コード例 #6
0
        private bool AddEdgeUnchecked(NodeId source, NodeId target, bool isLight)
        {
            BufferPointer <NodeEdgeListHeader> targetInEdges = InEdges.GetBufferPointer(target.Value);

            Contract.Assert(!targetInEdges.Buffer[targetInEdges.Index].IsSealed, "Attempted to add edge to sealed node");

            return(AddEdgeUnchecked(
                       source: source,
                       target: target,
                       targetInEdges: targetInEdges,
                       isLight: isLight,
                       bulkAddingTargetIncoming: false));
        }
コード例 #7
0
        private bool IsSealed(NodeId target)
        {
            BufferPointer <NodeEdgeListHeader> targetInEdges = InEdges.GetBufferPointer(target.Value);

            return(targetInEdges.Buffer[targetInEdges.Index].IsSealed);
        }
コード例 #8
0
 public IEnumerable <T> GetCorrespondents()
 {
     return(InEdges.GetCorrespondents().Union(OutEdges.GetCorrespondents()));
 }
コード例 #9
0
        /// <summary>
        /// Loads this graph from a given binary stream.
        /// </summary>
        private void Load(BuildXLReader reader)
        {
            m_lastNodeId = (int)reader.ReadUInt32();
            m_edgeCount  = reader.ReadInt32();
            Contract.Assume(m_lastNodeId <= NodeId.MaxValue);

            // Create buffer with space for in edges and out edges
            m_edgeBuffer.Initialize(m_edgeCount * 2);
            int edgeIndex = 0;

            // Read the out edges
            {
                var accessor = m_edgeBuffer.GetAccessor();

                // TODO: This loop takes 70% of the deserialization time; make faster.
                for (uint i = 1; i <= m_lastNodeId; ++i)
                {
                    int outNodeCount   = reader.ReadInt32Compact();
                    int startEdgeIndex = edgeIndex;
                    for (int j = 0; j < outNodeCount; ++j)
                    {
                        var outgoingEdge = Edge.Deserialize(reader);
                        accessor[edgeIndex] = outgoingEdge;
                        edgeIndex++;
                    }

                    OutEdges[i] = new NodeEdgeListHeader(startEdgeIndex, outNodeCount);
                }
            }

            // Read the count of in edges
            // TODO: This loop takes 10% of the deserialization time; make faster.
            for (uint i = 1; i <= m_lastNodeId; i++)
            {
                int nodeHeight = reader.ReadInt32Compact();
                NodeHeights[i] = nodeHeight;

                int inEdgeCount = reader.ReadInt32Compact();

                // first edge index starts at end of edge span for this node and is decrements as edges
                // are discovered and added below. At the end the first edge index will
                // be at the beginning of the span
                edgeIndex += inEdgeCount;
                InEdges[i] = new NodeEdgeListHeader(edgeIndex, inEdgeCount);
            }

            // Write each out edge set to graph and compute the in edges
            // TODO: This parallel loop takes 20% of the (sequential) deserialization time; make faster.
            Parallel.For(1, m_lastNodeId + 1,
                         (i) =>
            {
                NodeId node  = new NodeId((uint)i);
                var accessor = m_edgeBuffer.GetAccessor();
                foreach (var e in GetOutgoingEdges(node))
                {
                    var inEdge = new Edge(node, e.IsLight);

                    // Note: We access the InEdges array element directly, not via the ConcurrentDenseIndex's indexer property.
                    // As a result, we mutate the actual array element, instead of a copy.
                    var p     = InEdges.GetBufferPointer(e.OtherNode.Value);
                    var index = p.Buffer[p.Index].InterlockedDecrementFirstIndex();

                    // Set the prior index and point header at that index. The initial value
                    // to index should be set to the index after the span. So this will always
                    // set an index within the edge span
                    accessor[index] = inEdge;
                }
            });
        }
コード例 #10
0
 public ResearchNode InResearch()
 {
     return(InEdges.First().InResearch());
 }
コード例 #11
0
 public IEnumerable <ResearchNode> DirectPrerequisites()
 {
     return(InEdges.Select(e => e.InResearch()));
 }
コード例 #12
0
 public override int LayoutUpperPriority()
 {
     return(InEdges.Count());
 }
コード例 #13
0
 public override int DefaultPriority()
 {
     return(InEdges.Count() + OutEdges.Count());
 }