/// <summary> /// Sorts using the specified sorter. Will return null if there are no changes /// </summary> /// <param name="sortReason">The sort reason.</param> /// <param name="changes">The changes.</param> /// <returns></returns> private ISortedChangeSet <TObject, TKey> DoSort(SortReason sortReason, IChangeSet <TObject, TKey> changes = null) { if (changes != null) { _cache.Clone(changes); changes = _cache.CaptureChanges(); _haveReceivedData = true; if (_comparer == null) { return(null); } } //if the comparer is not set, return nothing if (_comparer == null || !_haveReceivedData) { return(null); } if (!_initialised) { sortReason = SortReason.InitialLoad; _initialised = true; } else if (changes != null && (_resetThreshold > 0 && changes.Count >= _resetThreshold)) { sortReason = SortReason.Reset; } IChangeSet <TObject, TKey> changeSet; switch (sortReason) { case SortReason.InitialLoad: { //For the first batch, changes may have arrived before the comparer was set. //therefore infer the first batch of changes from the cache _calculator = new IndexCalculator <TObject, TKey>(_comparer, _optimisations); changeSet = _calculator.Load(_cache); } break; case SortReason.Reset: { _calculator.Reset(_cache); changeSet = changes; } break; case SortReason.DataChanged: { changeSet = _calculator.Calculate(changes); } break; case SortReason.ComparerChanged: { changeSet = _calculator.ChangeComparer(_comparer); if (_resetThreshold > 0 && _cache.Count >= _resetThreshold) { sortReason = SortReason.Reset; _calculator.Reset(_cache); } else { sortReason = SortReason.Reorder; changeSet = _calculator.Reorder(); } } break; case SortReason.Reorder: { changeSet = _calculator.Reorder(); } break; default: throw new ArgumentOutOfRangeException(nameof(sortReason)); } Debug.Assert(changeSet != null, "changeSet != null"); if ((sortReason == SortReason.InitialLoad || sortReason == SortReason.DataChanged) && changeSet.Count == 0) { return(null); } if (sortReason == SortReason.Reorder && changeSet.Count == 0) { return(null); } _sorted = new KeyValueCollection <TObject, TKey>(_calculator.List, _comparer, sortReason, _optimisations); return(new SortedChangeSet <TObject, TKey>(_sorted, changeSet)); }