private bool TryRemove(TKey key, bool evicted, out TValue value, out ICollection <TValue>?bucket) { if (_cacheMap.TryGetValue(key, out value)) { if (Remove(key, value)) { TGroupKey groupMapping = MapToGroup(value); if (_buckets.TryGetValue(groupMapping, out SortedSet <TValue> bucketSet)) { bucket = bucketSet; TValue?last = bucketSet.Max; if (bucketSet.Remove(value !)) { if (bucket.Count == 0) { _buckets.Remove(groupMapping); _worstSortedValues.Remove(last); } else { UpdateSortedValues(bucketSet, last); } return(true); } } Removed?.Invoke(this, new SortedPoolRemovedEventArgs(key, value, groupMapping, evicted)); } } value = default; bucket = null; return(false); }
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(); } } }
/// <summary> /// Actual removal mechanism. /// </summary> protected virtual bool Remove(TKey key, TValue value) { _sortedValues.Remove(value); return(_cacheMap.Remove(key)); }