Ejemplo n.º 1
0
        /// <summary>
        /// Adding an edge to a Btc graph can do the following if the edge already exists:
        ///   1) not add the new edge, instead upgrade existing edge to type mixed ( == input and output)
        ///   2) not add the new edge, instead update the existing edge's edge counts if any are zero (means unknown)
        /// </summary>
        public override void AddEdge(CdmEdge e)
        {
            #region Data Quality Checks
            CdmEdgeBtc ebNew = e as CdmEdgeBtc;
            if (ebNew == null)
            {
                Msg.LogError("CdmGraphBtc.AddEdge cannot cast edge to CdmEdgeBtc");
                return;
            }

            // Check edge has been handed to us in correct format, that is Transaction in the source slot
            CdmNode n = FindNodeAtEndOfEdge(ebNew.NodeTargetId, ebNew.EdgeId);
            if (n != null)
            {
                // Above may seem a bit lax, but we dont know order things will be added to the graph, maybe node is not known yet
                if (n.NodeType != NodeType.Tx)
                {
                    Msg.LogError("CdmGraphBtc.AddEdge all edges must have a transaction as their source");
                    return;
                }
            }
            #endregion

            CdmEdgeBtc ebExisting = FindEdgeByNodeSourceAndTarget(ebNew.NodeSourceId, ebNew.NodeTargetId) as CdmEdgeBtc;
            if (ebExisting == null)
            {
                // New edge, just add to list
                _edges.Add(ebNew);
            }
            else
            {
                // Edge exists in graph already, upgrade it to type mixed if needed
                MergeExistingEdge(ebNew, ebExisting);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Add depth values to the graph fragment
        /// </summary>
        private void UpdateFragmentAddDepth(CdmRequest r, CdmGraph gFragmentFromPool)
        {
            // a) node process: if request.node == node being inspected, and depth = -1, make depth 0. If depth = anything else, leave it alone.
            // b) edge process: look at the nodes on either end of the edge (call them n1 and n2) and examine their depth values:
            //      n1  n2
            //      -1  -1  both unknown, should not happen, leave alone
            //       0  -1  make the -1 = 1 (same case as below, order doesnt matter)
            //      -1   X  make the -1 = X + 1 (same case as above, order doesnt matter)
            //       X   Y  both known, leave alone

            // a) Node process
            List <CdmNode> nodes = gFragmentFromPool.GetAllNodes();

            foreach (CdmNode n in nodes)
            {
                if (r.NodeId == n.NodeId)
                {
                    if (n.Depth == -1)
                    {
                        // the node we're looking at is the node that was asked for in the request. Now, if previously
                        // we didn't know it's depth we know now that it must be the first requested node for this graph.
                        n.Depth = 0;
                    }
                    break;
                }
            }

            // b) Edge process
            List <CdmEdge> edges = gFragmentFromPool.GetAllEdges();

            foreach (CdmEdge e in edges)
            {
                CdmNode n1 = null;
                CdmNode n2 = null;
                gFragmentFromPool.GetNodesAtEitherEndofEdge(e.EdgeId, out n1, out n2);
                if (n1.Depth == -1 && n2.Depth == -1)
                {
                    // both unknown, shouldn't happen, just leave alone
                    Msg.LogWarning("CdmCore.UpdateFragmentAddDepth() has both nodes unknown depth for edge: " + e.EdgeId);
                }
                else if (n1.Depth != -1 || n2.Depth != -1)
                {
                    // precisely one unknown, so now we know the other
                    if (n1.Depth == -1)
                    {
                        n1.Depth = n2.Depth + 1;
                    }
                    else
                    {
                        n2.Depth = n1.Depth + 1;
                    }
                }
                else
                {
                    // both known, this is fine where we're just refreshing known values, so leave alone
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// If the CdmPool can fulfill the request, return the graph fragment required, return null otherwise
        /// </summary>
        /// <param name="r">The request we want to fulfill, which is a node and a range from-to of edge numbers</param>
        /// <param name="isPerfectMatchRequired">When true, the pool must perfectly match request, when false will return whatever pool has, even if incomplete</param>
        /// <returns>Graph fragment that fully or partially fulfills request, or null</returns>
        private CdmGraph CanCdmPoolFulfillRequest(CdmRequest r, bool isPerfectMatchRequired)
        {
            if (r == null)
            {
                return(null);
            }
            CdmNode n = CdmPool.FindNodeById(r.NodeId);

            if (n == null)
            {
                return(null);
            }

            int edgesAskedForCount          = r.EdgeCountTo - r.EdgeCountFrom + 1;
            int edgesFoundCount             = 0;
            int endOfEdgeNodesAskedForCount = edgesAskedForCount;
            int endOfEdgeNodesFoundCount    = 0;

            // Add requested node to graph fragment we will send
            CdmGraph gFragment = CreateNewGraph(_adaptorSelector.GetChosenAdaptor().GetFamily());

            gFragment.AddNode(n);

            // Get requisite edges
            for (int i = r.EdgeCountFrom; i <= r.EdgeCountTo; i++)
            {
                // This searches both ways around, sender and receiver
                CdmEdge e = CdmPool.FindEdgeByNodeAndNumber(n.NodeId, i);
                if (e != null)
                {
                    // Store the edge
                    edgesFoundCount++;
                    gFragment.AddEdge(e);

                    // Store the node at the end of the edge
                    CdmNode eoen = CdmPool.FindNodeAtEndOfEdge(n.NodeId, e.EdgeId);
                    gFragment.AddNode(eoen);
                    endOfEdgeNodesFoundCount++;
                }
            }

            if (isPerfectMatchRequired)
            {
                if (edgesFoundCount >= edgesAskedForCount && endOfEdgeNodesFoundCount >= endOfEdgeNodesAskedForCount)
                {
                    return(gFragment);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                return(gFragment);
            }
        }
Ejemplo n.º 4
0
        public virtual void AddNode(CdmNode n)
        {
            // Only add if not already there
            CdmNode existing = FindNodeById(n.NodeId);

            if (existing == null)
            {
                _nodes.Add(n);
            }
        }
Ejemplo n.º 5
0
        public virtual void GetNodesAtEitherEndofEdge(string edgeId, out CdmNode n1, out CdmNode n2)
        {
            CdmEdge e = _edges.Find(c => (c.EdgeId == edgeId));

            if (e != null)
            {
                n1 = FindNodeById(e.NodeTargetId);
                n2 = FindNodeById(e.NodeSourceId);
            }
            else
            {
                n1 = null;
                n2 = null;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Adding a node to a Btc graph can do the following if the node already exists:
        ///   1) not add the new node, instead update the existing node's data
        /// </summary>
        public override void AddNode(CdmNode n)
        {
            #region Data Quality Checks
            CdmNodeBtc nbNew = n as CdmNodeBtc;
            if (nbNew == null)
            {
                Msg.LogError("CdmGraphBtc.AddNode cannot cast edge to CdmNodeBtc");
                return;
            }
            #endregion

            CdmNodeBtc nbExisting = FindNodeById(nbNew.NodeId) as CdmNodeBtc;
            if (nbExisting == null)
            {
                // New node, just add to list
                _nodes.Add(nbNew);
            }
            else
            {
                // Node exists in graph already, merge in any previously unknown data
                MergeExistingNode(nbNew, nbExisting);
            }
        }