예제 #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="capacity">Max capacity, after surpassing it elements will be removed based on last by <see cref="comparer"/>.</param>
 /// <param name="comparer">Comparer to sort items.</param>
 protected SortedPool(int capacity, IComparer <TValue> comparer)
 {
     _capacity = capacity;
     // ReSharper disable once VirtualMemberCallInConstructor
     _comparer     = GetUniqueComparer(comparer ?? throw new ArgumentNullException(nameof(comparer)));
     _cacheMap     = new Dictionary <TKey, TValue>(); // do not initialize it at the full capacity
     _buckets      = new Dictionary <TGroupKey, ICollection <TValue> >();
     _sortedValues = new DictionarySortedSet <TValue, TKey>(_comparer);
 }
예제 #2
0
        private IEnumerable <Transaction> Order(
            IEnumerable <IEnumerable <Transaction> > transactionsBySenderOrderedByNonce,
            IComparer <Transaction> comparer)
        {
            IEnumerator <Transaction>[] bySenderEnumerators = transactionsBySenderOrderedByNonce
                                                              .Select(g => g.GetEnumerator())
                                                              .ToArray();

            try
            {
                // we create a sorted list of head of each group of transactions. From:
                // A -> N0_P3, N1_P1, N1_P0, N3_P5...
                // B -> N4_P4, N5_P3, N6_P3...
                // We construct [N4_P4 (B), N0_P3 (A)] in sorted order by priority
                var transactions = new DictionarySortedSet <Transaction, IEnumerator <Transaction> >(comparer);

                for (int i = 0; i < bySenderEnumerators.Length; i++)
                {
                    IEnumerator <Transaction> enumerator = bySenderEnumerators[i];
                    if (enumerator.MoveNext())
                    {
                        transactions.Add(enumerator.Current !, enumerator);
                    }
                }

                // while there are still unreturned transactions
                while (transactions.Count > 0)
                {
                    // we take first transaction from sorting order, on first call: N4_P4 from B
                    var(tx, enumerator) = transactions.Min;

                    // we replace it by next transaction from same sender, on first call N5_P3 from B
                    transactions.Remove(tx);
                    if (enumerator.MoveNext())
                    {
                        transactions.Add(enumerator.Current !, enumerator);
                    }

                    // we return transactions in lazy manner, no need to sort more than will be taken into block
                    yield return(tx);
                }
            }
            finally
            {
                // disposing enumerators
                for (int i = 0; i < bySenderEnumerators.Length; i++)
                {
                    bySenderEnumerators[i].Dispose();
                }
            }
        }