a
This commit is contained in:
parent
6fa62a2761
commit
eec98af604
@ -3,54 +3,41 @@
|
|||||||
|
|
||||||
public sealed partial class ObservableRingBuffer<T>
|
public sealed partial class ObservableRingBuffer<T>
|
||||||
{
|
{
|
||||||
// TODO:not yet.
|
readonly RingBuffer<T> buffer;
|
||||||
readonly T[] buffer;
|
|
||||||
|
|
||||||
int head;
|
// TODO:SyncRoot
|
||||||
int count;
|
|
||||||
|
|
||||||
public ObservableRingBuffer(int capacity)
|
public ObservableRingBuffer()
|
||||||
{
|
{
|
||||||
this.buffer = new T[capacity];
|
this.buffer = new RingBuffer<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count => count;
|
public ObservableRingBuffer(IEnumerable<T> collection)
|
||||||
|
{
|
||||||
|
this.buffer = new RingBuffer<T>(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count => buffer.Count;
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = (head + index) % buffer.Length;
|
return this.buffer[index];
|
||||||
return this.buffer[i];
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
this.buffer[index] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddLast()
|
public void AddLast(T item)
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// AddLast
|
|
||||||
// AddFirst
|
|
||||||
//new LinkedList<int>().remo
|
|
||||||
//new Stack<int>().Push
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddFirst()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveLast()
|
public void AddLastRange(T[] items)
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFirst()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReverseEnumerable
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,27 @@ namespace ObservableCollections
|
|||||||
this.mask = buffer.Length - 1;
|
this.mask = buffer.Length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RingBuffer(IEnumerable<T> collection)
|
||||||
|
{
|
||||||
|
var array = collection.TryGetNonEnumeratedCount(out var count)
|
||||||
|
? new T[CalculateCapacity(count)]
|
||||||
|
: new T[8];
|
||||||
|
var i = 0;
|
||||||
|
foreach (var item in collection)
|
||||||
|
{
|
||||||
|
if (i == array.Length)
|
||||||
|
{
|
||||||
|
Array.Resize(ref array, i * 2);
|
||||||
|
}
|
||||||
|
array[i++] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.buffer = array;
|
||||||
|
this.head = 0;
|
||||||
|
this.count = i;
|
||||||
|
this.mask = buffer.Length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int CalculateCapacity(int size)
|
static int CalculateCapacity(int size)
|
||||||
{
|
{
|
||||||
size--;
|
size--;
|
||||||
@ -146,7 +167,12 @@ namespace ObservableCollections
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<T> GetEnumerator()
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return new Enumerator(GetSpan());
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||||
{
|
{
|
||||||
if (count == 0) yield break;
|
if (count == 0) yield break;
|
||||||
|
|
||||||
@ -220,17 +246,8 @@ namespace ObservableCollections
|
|||||||
|
|
||||||
public int IndexOf(T item)
|
public int IndexOf(T item)
|
||||||
{
|
{
|
||||||
var span = GetSpan();
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var v in span.First)
|
foreach (var v in this)
|
||||||
{
|
|
||||||
if (EqualityComparer<T>.Default.Equals(item, v))
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
foreach (var v in span.Second)
|
|
||||||
{
|
{
|
||||||
if (EqualityComparer<T>.Default.Equals(item, v))
|
if (EqualityComparer<T>.Default.Equals(item, v))
|
||||||
{
|
{
|
||||||
@ -241,6 +258,17 @@ namespace ObservableCollections
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T[] ToArray()
|
||||||
|
{
|
||||||
|
var result = new T[count];
|
||||||
|
var i = 0;
|
||||||
|
foreach (var item in this)
|
||||||
|
{
|
||||||
|
result[i++] = item;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void IList<T>.Insert(int index, T item)
|
void IList<T>.Insert(int index, T item)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
@ -258,7 +286,7 @@ namespace ObservableCollections
|
|||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
{
|
{
|
||||||
return GetEnumerator();
|
return ((IEnumerable<T>)this).GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
[DoesNotReturn]
|
[DoesNotReturn]
|
||||||
@ -266,15 +294,65 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
throw new InvalidOperationException("RingBuffer is empty.");
|
throw new InvalidOperationException("RingBuffer is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
ReadOnlySpan<T>.Enumerator firstEnumerator;
|
||||||
|
ReadOnlySpan<T>.Enumerator secondEnumerator;
|
||||||
|
bool useFirst;
|
||||||
|
|
||||||
|
public Enumerator(RingBufferSpan<T> span)
|
||||||
|
{
|
||||||
|
this.firstEnumerator = span.First.GetEnumerator();
|
||||||
|
this.secondEnumerator = span.Second.GetEnumerator();
|
||||||
|
this.useFirst = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (useFirst)
|
||||||
|
{
|
||||||
|
if (firstEnumerator.MoveNext())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
useFirst = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondEnumerator.MoveNext())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (useFirst)
|
||||||
|
{
|
||||||
|
return firstEnumerator.Current;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return secondEnumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref struct RingBufferSpan<T>
|
public ref struct RingBufferSpan<T>
|
||||||
{
|
{
|
||||||
public readonly Span<T> First;
|
public readonly ReadOnlySpan<T> First;
|
||||||
public readonly Span<T> Second;
|
public readonly ReadOnlySpan<T> Second;
|
||||||
public readonly int Count;
|
public readonly int Count;
|
||||||
|
|
||||||
public RingBufferSpan(Span<T> first, Span<T> second, int count)
|
internal RingBufferSpan(ReadOnlySpan<T> first, ReadOnlySpan<T> second, int count)
|
||||||
{
|
{
|
||||||
First = first;
|
First = first;
|
||||||
Second = second;
|
Second = second;
|
||||||
|
@ -11,7 +11,7 @@ namespace ObservableCollections.Tests
|
|||||||
public class RingBufferTest
|
public class RingBufferTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Foo()
|
public void All()
|
||||||
{
|
{
|
||||||
var list = new RingBuffer<int>();
|
var list = new RingBuffer<int>();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user