This commit is contained in:
neuecc 2021-08-19 19:36:30 +09:00
parent 6fa62a2761
commit eec98af604
3 changed files with 108 additions and 43 deletions

View File

@ -3,54 +3,41 @@
public sealed partial class ObservableRingBuffer<T>
{
// TODO:not yet.
readonly T[] buffer;
readonly RingBuffer<T> buffer;
int head;
int count;
// TODO:SyncRoot
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]
{
get
{
var i = (head + index) % buffer.Length;
return this.buffer[i];
return this.buffer[index];
}
set
{
this.buffer[index] = value;
}
}
public void AddLast()
{
// AddLast
// AddFirst
//new LinkedList<int>().remo
//new Stack<int>().Push
}
public void AddFirst()
public void AddLast(T item)
{
}
public void RemoveLast()
public void AddLastRange(T[] items)
{
}
public void RemoveFirst()
{
}
// GetReverseEnumerable
}
}
}

View File

@ -26,6 +26,27 @@ namespace ObservableCollections
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)
{
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;
@ -220,17 +246,8 @@ namespace ObservableCollections
public int IndexOf(T item)
{
var span = GetSpan();
var i = 0;
foreach (var v in span.First)
{
if (EqualityComparer<T>.Default.Equals(item, v))
{
return i;
}
i++;
}
foreach (var v in span.Second)
foreach (var v in this)
{
if (EqualityComparer<T>.Default.Equals(item, v))
{
@ -241,6 +258,17 @@ namespace ObservableCollections
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)
{
throw new NotSupportedException();
@ -258,7 +286,7 @@ namespace ObservableCollections
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
return ((IEnumerable<T>)this).GetEnumerator();
}
[DoesNotReturn]
@ -266,15 +294,65 @@ namespace ObservableCollections
{
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 readonly Span<T> First;
public readonly Span<T> Second;
public readonly ReadOnlySpan<T> First;
public readonly ReadOnlySpan<T> Second;
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;
Second = second;

View File

@ -11,7 +11,7 @@ namespace ObservableCollections.Tests
public class RingBufferTest
{
[Fact]
public void Foo()
public void All()
{
var list = new RingBuffer<int>();