/// <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); }
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(); } } }