/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.Linq; using QuantConnect.Util; using QuantConnect.Data; using System.Collections; using System.Collections.Generic; namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators { /// /// Provides an enumerator for sorting collections of objects based on a specified property. /// The sorting occurs lazily, only when enumeration begins. /// /// The type of the key used for sorting. public sealed class SortEnumerator : IEnumerator, IDisposable { private readonly IEnumerable _data; #pragma warning disable CA2213 // call csutom DisposeSafely() in Dispose() private IEnumerator _sortedEnumerator; #pragma warning restore CA2213 // call csutom DisposeSafely() in Dispose() private readonly Func _keySelector; /// /// Initializes a new instance of the class. /// /// The collection of to enumerate over. /// A function that defines the key to sort by. Defaults to sorting by . public SortEnumerator(IEnumerable data, Func keySelector = null) { _data = data; _sortedEnumerator = GetSortedData().GetEnumerator(); _keySelector = keySelector ??= baseData => (TKey)(object)baseData.EndTime; } /// /// Static method to wrap an enumerable with the sort enumerator. /// /// Indicates if the data is pre-sorted. /// The data to be wrapped into the enumerator. /// An enumerator over the . public static IEnumerator TryWrapSortEnumerator(bool preSorted, IEnumerable data) { return preSorted ? new SortEnumerator(data) : data.GetEnumerator(); } /// /// Lazily retrieves the sorted data. /// /// An enumerable collection of . private IEnumerable GetSortedData() { foreach (var item in _data.OrderBy(_keySelector)) { yield return item; } } object IEnumerator.Current => Current; /// /// Gets the current element in the collection. /// public BaseData Current { get => _sortedEnumerator.Current; } /// /// Advances the enumerator to the next element of the collection. /// /// /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// public bool MoveNext() { return _sortedEnumerator.MoveNext(); } /// /// Resets the enumerator to its initial position, which is before the first element in the collection. /// public void Reset() { _sortedEnumerator = null; } /// /// Releases all resources used by the and suppresses finalization. /// public void Dispose() { _sortedEnumerator?.DisposeSafely(); } } }