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