forked from mirror/DotRecast
Support split special case
This commit is contained in:
parent
c47cc79552
commit
609508c94f
|
@ -191,14 +191,17 @@ namespace DotRecast.Core.Buffers
|
|||
public T[] ToArray()
|
||||
{
|
||||
T[] newArray = new T[Size];
|
||||
|
||||
var span1 = ArrayOne();
|
||||
span1.CopyTo(newArray.AsSpan());
|
||||
ArrayTwo().CopyTo(newArray.AsSpan(span1.Length..));
|
||||
|
||||
CopyTo(newArray);
|
||||
return newArray;
|
||||
}
|
||||
|
||||
public void CopyTo(Span<T> destination)
|
||||
{
|
||||
var span1 = ArrayOne();
|
||||
span1.CopyTo(destination);
|
||||
ArrayTwo().CopyTo(destination[span1.Length..]);
|
||||
}
|
||||
|
||||
private void ThrowIfEmpty(string message = "Cannot access an empty buffer.")
|
||||
{
|
||||
if (IsEmpty)
|
||||
|
@ -232,7 +235,7 @@ namespace DotRecast.Core.Buffers
|
|||
: index - Capacity);
|
||||
}
|
||||
|
||||
private Span<T> ArrayOne()
|
||||
internal Span<T> ArrayOne()
|
||||
{
|
||||
if (IsEmpty)
|
||||
{
|
||||
|
@ -247,7 +250,7 @@ namespace DotRecast.Core.Buffers
|
|||
return new Span<T>(_buffer, _start, _buffer.Length - _start);
|
||||
}
|
||||
|
||||
private Span<T> ArrayTwo()
|
||||
internal Span<T> ArrayTwo()
|
||||
{
|
||||
if (IsEmpty)
|
||||
{
|
||||
|
@ -262,11 +265,6 @@ namespace DotRecast.Core.Buffers
|
|||
return new Span<T>(_buffer, 0, _end);
|
||||
}
|
||||
|
||||
internal ReadOnlySpan<T> GetBufferSpan()
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator() => new Enumerator(this);
|
||||
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
|
||||
|
|
|
@ -6,9 +6,9 @@ namespace DotRecast.Core.Buffers
|
|||
{
|
||||
public static class RcCyclicBuffers
|
||||
{
|
||||
public static long Sum(this RcCyclicBuffer<long> source)
|
||||
public static long Sum(this ReadOnlySpan<long> source)
|
||||
{
|
||||
var buffer = source.GetBufferSpan();
|
||||
var buffer = source;
|
||||
var result = 0L;
|
||||
if (Vector.IsHardwareAccelerated)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace DotRecast.Core.Buffers
|
|||
vecSum += vec;
|
||||
|
||||
result = Vector.Dot(vecSum, Vector<long>.One);
|
||||
var remainder = source.Size % Vector<long>.Count;
|
||||
var remainder = source.Length % Vector<long>.Count;
|
||||
buffer = buffer[^remainder..];
|
||||
}
|
||||
|
||||
|
@ -28,17 +28,17 @@ namespace DotRecast.Core.Buffers
|
|||
return result;
|
||||
}
|
||||
|
||||
public static double Average(this RcCyclicBuffer<long> source)
|
||||
public static double Average(this ReadOnlySpan<long> source)
|
||||
{
|
||||
if (0 >= source.Size)
|
||||
if (0 >= source.Length)
|
||||
return 0;
|
||||
|
||||
return source.Sum() / (double)source.Size;
|
||||
return source.Sum() / (double)source.Length;
|
||||
}
|
||||
|
||||
public static long Min(this RcCyclicBuffer<long> source)
|
||||
private static long Min(this ReadOnlySpan<long> source)
|
||||
{
|
||||
var buffer = source.GetBufferSpan();
|
||||
var buffer = source;
|
||||
var result = long.MaxValue;
|
||||
|
||||
if (Vector.IsHardwareAccelerated)
|
||||
|
@ -52,7 +52,7 @@ namespace DotRecast.Core.Buffers
|
|||
for (int i = 0; i < Vector<long>.Count; i++)
|
||||
result = Math.Min(result, vecMin[i]);
|
||||
|
||||
var remainder = source.Size % Vector<long>.Count;
|
||||
var remainder = source.Length % Vector<long>.Count;
|
||||
buffer = buffer[^remainder..];
|
||||
}
|
||||
|
||||
|
@ -62,9 +62,9 @@ namespace DotRecast.Core.Buffers
|
|||
return result;
|
||||
}
|
||||
|
||||
public static long Max(this RcCyclicBuffer<long> source)
|
||||
private static long Max(this ReadOnlySpan<long> source)
|
||||
{
|
||||
var buffer = source.GetBufferSpan();
|
||||
var buffer = source;
|
||||
var result = long.MinValue;
|
||||
|
||||
if (Vector.IsHardwareAccelerated)
|
||||
|
@ -78,7 +78,7 @@ namespace DotRecast.Core.Buffers
|
|||
for (int i = 0; i < Vector<long>.Count; i++)
|
||||
result = Math.Max(result, vecMax[i]);
|
||||
|
||||
var remainder = source.Size % Vector<long>.Count;
|
||||
var remainder = source.Length % Vector<long>.Count;
|
||||
buffer = buffer[^remainder..];
|
||||
}
|
||||
|
||||
|
@ -87,5 +87,33 @@ namespace DotRecast.Core.Buffers
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long Sum(this RcCyclicBuffer<long> source)
|
||||
{
|
||||
return Sum(source.ArrayOne()) + Sum(source.ArrayTwo());
|
||||
}
|
||||
|
||||
public static double Average(this RcCyclicBuffer<long> source)
|
||||
{
|
||||
return Sum(source) / (double)source.Size;
|
||||
}
|
||||
|
||||
public static long Min(this RcCyclicBuffer<long> source)
|
||||
{
|
||||
var firstHalf = source.ArrayOne();
|
||||
var secondHalf = source.ArrayTwo();
|
||||
var a = firstHalf.Length > 0 ? Min(firstHalf) : long.MaxValue;
|
||||
var b = secondHalf.Length > 0 ? Min(secondHalf) : long.MaxValue;
|
||||
return Math.Min(a, b);
|
||||
}
|
||||
|
||||
public static long Max(this RcCyclicBuffer<long> source)
|
||||
{
|
||||
var firstHalf = source.ArrayOne();
|
||||
var secondHalf = source.ArrayTwo();
|
||||
var a = firstHalf.Length > 0 ? Max(firstHalf) : long.MinValue;
|
||||
var b = secondHalf.Length > 0 ? Max(secondHalf) : long.MinValue;
|
||||
return Math.Max(a, b);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -394,4 +394,56 @@ public class RcCyclicBufferTests
|
|||
var buffer = new RcCyclicBuffer<long>(refValues.Length, refValues);
|
||||
Assert.That(RcCyclicBuffers.Max(buffer), Is.EqualTo(refValues.Max()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RcCyclicBuffers_SumDeleted()
|
||||
{
|
||||
var initialValues = Enumerable.Range(-100, 211).Select(x => (long)x).ToArray();
|
||||
var refValues = initialValues.Skip(1).SkipLast(1).ToArray();
|
||||
var buffer = new RcCyclicBuffer<long>(initialValues.Length, initialValues);
|
||||
buffer.PopBack();
|
||||
buffer.PopFront();
|
||||
|
||||
Assert.That(RcCyclicBuffers.Sum(buffer), Is.EqualTo(refValues.Sum()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RcCyclicBuffers_SumSplit()
|
||||
{
|
||||
var refValues = Enumerable.Range(-100, 211).Select(x => (long)x).ToArray();
|
||||
var buffer = new RcCyclicBuffer<long>(refValues.Length, refValues);
|
||||
buffer.PopFront();
|
||||
buffer.PushBack(refValues[0]);
|
||||
Assert.That(RcCyclicBuffers.Sum(buffer), Is.EqualTo(refValues.Sum()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RcCyclicBuffers_AverageSplit()
|
||||
{
|
||||
var refValues = Enumerable.Range(-100, 211).Select(x => (long)x).ToArray();
|
||||
var buffer = new RcCyclicBuffer<long>(refValues.Length, refValues);
|
||||
buffer.PopFront();
|
||||
buffer.PushBack(refValues[0]);
|
||||
Assert.That(RcCyclicBuffers.Average(buffer), Is.EqualTo(refValues.Average()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RcCyclicBuffers_MinSplit()
|
||||
{
|
||||
var refValues = Enumerable.Range(-100, 211).Select(x => (long)x).ToArray();
|
||||
var buffer = new RcCyclicBuffer<long>(refValues.Length, refValues);
|
||||
buffer.PopFront();
|
||||
buffer.PushBack(refValues[0]);
|
||||
Assert.That(RcCyclicBuffers.Min(buffer), Is.EqualTo(refValues.Min()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RcCyclicBuffers_MaxSplit()
|
||||
{
|
||||
var refValues = Enumerable.Range(-100, 211).Select(x => (long)x).ToArray();
|
||||
var buffer = new RcCyclicBuffer<long>(refValues.Length, refValues);
|
||||
buffer.PopFront();
|
||||
buffer.PushBack(refValues[0]);
|
||||
Assert.That(RcCyclicBuffers.Max(buffer), Is.EqualTo(refValues.Max()));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue