コード例 #1
0
        /// <summary>
        /// Merges the sets represented by this node and the other node into a single set.
        /// Returns whether or not the nodes were disjoint before the union operation (i.e. if the operation had an effect).
        /// </summary>
        /// <returns>True when the union had an effect, false when the nodes were already in the same set.</returns>
        public bool Union(UnionFindNode other)
        {
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }
            var root1 = this.Find();
            var root2 = other.Find();

            if (ReferenceEquals(root1, root2))
            {
                return(false);
            }

            if (root1.NodeId < root2.NodeId)
            {
                root2._parent = root1;
            }
            else
            {
                root1._parent = root2;
            }

            /*
             * if (root1._rank < root2._rank) {
             * root1._parent = root2;
             * } else if (root1._rank > root2._rank) {
             * root2._parent = root1;
             * } else {
             * root2._parent = root1;
             * root1._rank++;
             * }
             */
            return(true);
        }
コード例 #2
0
ファイル: TransactionGrouper.cs プロジェクト: zhxymh/AElf
        private List <List <Transaction> > GroupParallelizables(List <TransactionWithResourceInfo> txsWithResources)
        {
            var resourceUnionSet          = new Dictionary <int, UnionFindNode>();
            var transactionResourceHandle = new Dictionary <Transaction, int>();
            var groups = new List <List <Transaction> >();

            foreach (var txWithResource in txsWithResources)
            {
                UnionFindNode first                   = null;
                var           transaction             = txWithResource.Transaction;
                var           transactionResourceInfo = txWithResource.TransactionResourceInfo;

                // Add resources to disjoint-set, later each resource will be connected to a node id, which will be our group id
                foreach (var resource in transactionResourceInfo.Paths.Select(p => p.GetHashCode()))
                {
                    if (!resourceUnionSet.TryGetValue(resource, out var node))
                    {
                        node = new UnionFindNode();
                        resourceUnionSet.Add(resource, node);
                    }

                    if (first == null)
                    {
                        first = node;
                        transactionResourceHandle.Add(transaction, resource);
                    }
                    else
                    {
                        node.Union(first);
                    }
                }
            }

            var grouped = new Dictionary <int, List <Transaction> >();

            foreach (var txWithResource in txsWithResources)
            {
                var transaction = txWithResource.Transaction;
                if (!transactionResourceHandle.TryGetValue(transaction, out var firstResource))
                {
                    continue;
                }

                // Node Id will be our group id
                var gId = resourceUnionSet[firstResource].Find().NodeId;

                if (!grouped.TryGetValue(gId, out var gTransactions))
                {
                    gTransactions = new List <Transaction>();
                    grouped.Add(gId, gTransactions);
                }

                // Add transaction to its group
                gTransactions.Add(transaction);
            }

            groups.AddRange(grouped.Values);

            return(groups);
        }
コード例 #3
0
 /// <summary>
 /// Determines whether or not this node and the other node are in the same set.
 /// </summary>
 public bool IsUnionedWith(UnionFindNode other)
 {
     if (other == null)
     {
         throw new ArgumentNullException("other");
     }
     return(ReferenceEquals(Find(), other.Find()));
 }
コード例 #4
0
 /// <summary>
 /// Returns the current representative of the set this node is in.
 /// Note that the representative is only accurate untl the next Union operation.
 /// </summary>
 public UnionFindNode Find()
 {
     if (!ReferenceEquals(_parent, this))
     {
         _parent = _parent.Find();
     }
     return(_parent);
 }
コード例 #5
0
 /// <summary>
 /// Creates a new disjoint node, representative of a set containing only the new node.
 /// </summary>
 public UnionFindNode()
 {
     _parent = this;
     NodeId  = Interlocked.Increment(ref _nextId);
 }