move QuickCollections to the PCEHawk core where it is used, since we don't expect to use it elsewhere, and one of it's advantages was speculating that being in the same assembly would give it good inlining, so being in a common library was negating this
This commit is contained in:
parent
dc656ccb23
commit
249259d7b3
|
@ -1,112 +1,110 @@
|
||||||
#nullable disable
|
using System;
|
||||||
|
|
||||||
using System;
|
namespace BizHawk.Emulation.Cores.PCEngine
|
||||||
|
{
|
||||||
namespace BizHawk.Common
|
// If you're wondering what the point of this is: It's mostly to have .Clear() be fast.
|
||||||
{
|
// only intended to be used with value types. If used on references you may get GC issues.
|
||||||
// If you're wondering what the point of this is: It's mostly to have .Clear() be fast.
|
// Also, being in the same assembly means the JITer might inline these calls.
|
||||||
// only intended to be used with value types. If used on references you may get GC issues.
|
// There is less overhead by not being dynamically resizable and stuff.
|
||||||
// Also, being in the same assembly means the JITer might inline these calls.
|
public sealed class QuickList<T> where T : struct
|
||||||
// There is less overhead by not being dynamically resizable and stuff.
|
{
|
||||||
public sealed class QuickList<T> where T : struct
|
public T[] buffer;
|
||||||
{
|
public int Position;
|
||||||
public T[] buffer;
|
|
||||||
public int Position;
|
public QuickList(int capacity)
|
||||||
|
{
|
||||||
public QuickList(int capacity)
|
buffer = new T[capacity];
|
||||||
{
|
}
|
||||||
buffer = new T[capacity];
|
|
||||||
}
|
public T this[int index]
|
||||||
|
{
|
||||||
public T this[int index]
|
get => buffer[index];
|
||||||
{
|
set => buffer[index] = value;
|
||||||
get => buffer[index];
|
}
|
||||||
set => buffer[index] = value;
|
|
||||||
}
|
public int Count => Position;
|
||||||
|
|
||||||
public int Count => Position;
|
public void Add(T item)
|
||||||
|
{
|
||||||
public void Add(T item)
|
buffer[Position++] = item;
|
||||||
{
|
}
|
||||||
buffer[Position++] = item;
|
|
||||||
}
|
public void Clear()
|
||||||
|
{
|
||||||
public void Clear()
|
Position = 0;
|
||||||
{
|
}
|
||||||
Position = 0;
|
}
|
||||||
}
|
|
||||||
}
|
// and the point of this one is to be easier to serialize quickly. AND fast to clear.
|
||||||
|
// only intended to be used with value types. If used on references you may get GC issues.
|
||||||
// and the point of this one is to be easier to serialize quickly. AND fast to clear.
|
public sealed class QuickQueue<T> where T : struct
|
||||||
// only intended to be used with value types. If used on references you may get GC issues.
|
{
|
||||||
public sealed class QuickQueue<T> where T : struct
|
public T[] buffer;
|
||||||
{
|
public int head;
|
||||||
public T[] buffer;
|
public int tail;
|
||||||
public int head;
|
public int size;
|
||||||
public int tail;
|
|
||||||
public int size;
|
public QuickQueue(int capacity)
|
||||||
|
{
|
||||||
public QuickQueue(int capacity)
|
buffer = new T[capacity];
|
||||||
{
|
}
|
||||||
buffer = new T[capacity];
|
|
||||||
}
|
public int Count => size;
|
||||||
|
|
||||||
public int Count => size;
|
/// <exception cref="Exception">called while at capacity</exception>
|
||||||
|
public void Enqueue(T item)
|
||||||
/// <exception cref="Exception">called while at capacity</exception>
|
{
|
||||||
public void Enqueue(T item)
|
if (size >= buffer.Length)
|
||||||
{
|
throw new Exception($"{nameof(QuickQueue<T>)} capacity breached!");
|
||||||
if (size >= buffer.Length)
|
|
||||||
throw new Exception($"{nameof(QuickQueue<T>)} capacity breached!");
|
buffer[tail] = item;
|
||||||
|
tail = (tail + 1) % buffer.Length;
|
||||||
buffer[tail] = item;
|
size++;
|
||||||
tail = (tail + 1) % buffer.Length;
|
}
|
||||||
size++;
|
|
||||||
}
|
public T[] ToArray(int elemSize)
|
||||||
|
{
|
||||||
public T[] ToArray(int elemSize)
|
T[] ret = new T[size];
|
||||||
{
|
int todo;
|
||||||
T[] ret = new T[size];
|
if (tail > head) todo = tail - head;
|
||||||
int todo;
|
else todo = buffer.Length - head;
|
||||||
if (tail > head) todo = tail - head;
|
Buffer.BlockCopy(buffer, head, ret, 0, elemSize * todo);
|
||||||
else todo = buffer.Length - head;
|
int todo2;
|
||||||
Buffer.BlockCopy(buffer, head, ret, 0, elemSize * todo);
|
if (tail < head) todo2 = tail;
|
||||||
int todo2;
|
else todo2 = 0;
|
||||||
if (tail < head) todo2 = tail;
|
if (todo2 != 0) Buffer.BlockCopy(buffer, 0, ret, todo, elemSize * todo2);
|
||||||
else todo2 = 0;
|
return ret;
|
||||||
if (todo2 != 0) Buffer.BlockCopy(buffer, 0, ret, todo, elemSize * todo2);
|
}
|
||||||
return ret;
|
|
||||||
}
|
/// <exception cref="Exception">called while empty</exception>
|
||||||
|
public T Dequeue()
|
||||||
/// <exception cref="Exception">called while empty</exception>
|
{
|
||||||
public T Dequeue()
|
if (size == 0)
|
||||||
{
|
throw new Exception($"{nameof(QuickQueue<T>)} is empty!");
|
||||||
if (size == 0)
|
|
||||||
throw new Exception($"{nameof(QuickQueue<T>)} is empty!");
|
T item = buffer[head];
|
||||||
|
head = (head + 1) % buffer.Length;
|
||||||
T item = buffer[head];
|
size--;
|
||||||
head = (head + 1) % buffer.Length;
|
return item;
|
||||||
size--;
|
}
|
||||||
return item;
|
|
||||||
}
|
public void Clear()
|
||||||
|
{
|
||||||
public void Clear()
|
head = 0;
|
||||||
{
|
tail = 0;
|
||||||
head = 0;
|
size = 0;
|
||||||
tail = 0;
|
}
|
||||||
size = 0;
|
|
||||||
}
|
public T[] GetBuffer()
|
||||||
|
{
|
||||||
public T[] GetBuffer()
|
return buffer;
|
||||||
{
|
}
|
||||||
return buffer;
|
|
||||||
}
|
public void SignalBufferFilled(int count)
|
||||||
|
{
|
||||||
public void SignalBufferFilled(int count)
|
head = 0;
|
||||||
{
|
tail = count;
|
||||||
head = 0;
|
size = count;
|
||||||
tail = count;
|
}
|
||||||
size = count;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue