BufferedEnumerator that keeps 5 tokens in memory instead of 12,000,000
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace ParadoxSaveParser.Lib;
|
||||
|
||||
/// <summary>
|
||||
/// Enumerator wrapper that stores <c>N/2</c> items before and <c>N/2-1</c> after <c>Current</c> item.
|
||||
/// </summary>
|
||||
/// <code language="cs">
|
||||
/// IEnumerator<int> Enumerator()
|
||||
/// {
|
||||
/// for(int i = 0; i < 6; i++)
|
||||
/// yield return i;
|
||||
/// }
|
||||
///
|
||||
/// var en = Enumerator();
|
||||
/// var bufen = new BufferedEnumerator<int>(en, 5);
|
||||
///
|
||||
/// while(bufen.MoveNext())
|
||||
/// {
|
||||
/// var cur = bufen.Current;
|
||||
/// for (var prev = cur.List?.First; prev != cur; prev = prev?.Next)
|
||||
/// Console.Write($"{prev?.Value} ");
|
||||
///
|
||||
/// Console.Write($"| {cur.Value} |");
|
||||
///
|
||||
/// for (var next = cur.Next; next != null; next = next.Next)
|
||||
/// Console.Write($" {next.Value}");
|
||||
/// Console.WriteLine();
|
||||
/// }
|
||||
/// </code>
|
||||
/// Output:
|
||||
/// <code>
|
||||
/// | 0 | 1 2 3 4
|
||||
/// 0 | 1 | 2 3 4
|
||||
/// 0 1 | 2 | 3 4
|
||||
/// 1 2 | 3 | 4 5
|
||||
/// 2 3 | 4 | 5
|
||||
/// 3 4 | 5 |
|
||||
/// </code>
|
||||
public class BufferedEnumerator<T> : IEnumerator<LinkedListNode<T>>
|
||||
{
|
||||
private IEnumerator<T> _enumerator;
|
||||
private int _bufferSize;
|
||||
LinkedList<T> _llist = new();
|
||||
private LinkedListNode<T>? _currentNode;
|
||||
private int _currentNodeIndex = -1;
|
||||
|
||||
public BufferedEnumerator(IEnumerator<T> enumerator, int bufferSize)
|
||||
{
|
||||
_enumerator = enumerator;
|
||||
_bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if(_currentNodeIndex >= _bufferSize / 2)
|
||||
_llist.RemoveFirst();
|
||||
|
||||
while (_llist.Count < _bufferSize && _enumerator.MoveNext())
|
||||
{
|
||||
_llist.AddLast(_enumerator.Current);
|
||||
}
|
||||
if (_llist.Count == 0)
|
||||
return false;
|
||||
|
||||
_currentNodeIndex++;
|
||||
_currentNode = _currentNode == null ? _llist.First : _currentNode.Next;
|
||||
return _currentNode != null;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public LinkedListNode<T> Current => _currentNode!;
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user