mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
116 lines
2.8 KiB
C#
116 lines
2.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
|
|
namespace Wabbajack.Common.CSP
|
|
{
|
|
public class RingBuffer<T> : IEnumerable<T>
|
|
{
|
|
private int _size;
|
|
private int _length;
|
|
private int _tail;
|
|
private int _head;
|
|
private T[] _arr;
|
|
|
|
public RingBuffer(int size = 8)
|
|
{
|
|
_size = size;
|
|
_arr = new T[size];
|
|
_tail = 0;
|
|
_length = 0;
|
|
_head = 0;
|
|
}
|
|
|
|
public T Pop()
|
|
{
|
|
if (_length == 0)
|
|
throw new InvalidDataException("Pop on empty buffer");
|
|
var val = _arr[_tail];
|
|
_arr[_tail] = default;
|
|
_tail = (_tail + 1) % _size;
|
|
_length -= 1;
|
|
return val;
|
|
}
|
|
|
|
public T Peek()
|
|
{
|
|
return _length == 0 ? default : _arr[_tail];
|
|
}
|
|
|
|
public void Unshift(T x)
|
|
{
|
|
_arr[_head] = x;
|
|
_head = (_head + 1) % _size;
|
|
_length += 1;
|
|
}
|
|
|
|
public void UnboundedUnshift(T x)
|
|
{
|
|
if (_length + 1 == _size)
|
|
Resize();
|
|
Unshift(x);
|
|
}
|
|
|
|
public bool IsEmpty => _length == 0;
|
|
public int Length => _length;
|
|
|
|
private void Resize()
|
|
{
|
|
var new_arr_size = _size * 2;
|
|
var new_arr = new T[new_arr_size];
|
|
if (_tail < _head)
|
|
{
|
|
Array.Copy(_arr, _tail, new_arr, 0, _length);
|
|
_tail = 0;
|
|
_head = _length;
|
|
_arr = new_arr;
|
|
_size = new_arr_size;
|
|
}
|
|
else if (_tail > _head)
|
|
{
|
|
Array.Copy(_arr, _tail, new_arr, 0, _size - _tail);
|
|
Array.Copy(_arr, 0, new_arr, (_size - _tail), _head);
|
|
_tail = 0;
|
|
_head = _length;
|
|
_arr = new_arr;
|
|
_size = new_arr_size;
|
|
}
|
|
else
|
|
{
|
|
_tail = 0;
|
|
_head = 0;
|
|
_arr = new_arr;
|
|
_size = new_arr_size;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Filers out all items where should_keep(itm) returns false
|
|
/// </summary>
|
|
/// <param name="should_keep"></param>
|
|
public void Cleanup(Func<T, bool> should_keep)
|
|
{
|
|
for (var idx = 0; idx < _length; idx++)
|
|
{
|
|
var v = Pop();
|
|
if (should_keep(v))
|
|
{
|
|
Unshift(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
public IEnumerator<T> GetEnumerator()
|
|
{
|
|
while (!IsEmpty)
|
|
yield return Pop();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
}
|
|
}
|