189 lines
4.0 KiB
C#
189 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
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.
|
|
// Also, being in the same assembly means the JITer might inline these calls.
|
|
// 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 QuickList(int capacity)
|
|
{
|
|
buffer = new T[capacity];
|
|
}
|
|
|
|
public T this[int index]
|
|
{
|
|
get => buffer[index];
|
|
set => buffer[index] = value;
|
|
}
|
|
|
|
public int Count => Position;
|
|
|
|
public void Add(T item)
|
|
{
|
|
buffer[Position++] = item;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
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.
|
|
public sealed class QuickQueue<T> where T : struct
|
|
{
|
|
public T[] buffer;
|
|
public int head;
|
|
public int tail;
|
|
public int size;
|
|
|
|
public QuickQueue(int capacity)
|
|
{
|
|
buffer = new T[capacity];
|
|
}
|
|
|
|
public int Count => size;
|
|
|
|
public void Enqueue(T item)
|
|
{
|
|
if (size >= buffer.Length)
|
|
throw new Exception($"{nameof(QuickQueue<T>)} capacity breached!");
|
|
|
|
buffer[tail] = item;
|
|
tail = (tail + 1) % buffer.Length;
|
|
size++;
|
|
}
|
|
|
|
public T[] ToArray(int elemSize)
|
|
{
|
|
T[] ret = new T[size];
|
|
int todo;
|
|
if (tail > head) todo = tail - head;
|
|
else todo = buffer.Length - head;
|
|
Buffer.BlockCopy(buffer, head, ret, 0, elemSize * todo);
|
|
int todo2;
|
|
if (tail < head) todo2 = tail;
|
|
else todo2 = 0;
|
|
if (todo2 != 0) Buffer.BlockCopy(buffer, 0, ret, todo, elemSize * todo2);
|
|
return ret;
|
|
}
|
|
|
|
public T Dequeue()
|
|
{
|
|
if (size == 0)
|
|
throw new Exception($"{nameof(QuickQueue<T>)} is empty!");
|
|
|
|
T item = buffer[head];
|
|
head = (head + 1) % buffer.Length;
|
|
size--;
|
|
return item;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
head = 0;
|
|
tail = 0;
|
|
size = 0;
|
|
}
|
|
|
|
public T[] GetBuffer()
|
|
{
|
|
return buffer;
|
|
}
|
|
|
|
public void SignalBufferFilled(int count)
|
|
{
|
|
head = 0;
|
|
tail = count;
|
|
size = count;
|
|
}
|
|
}
|
|
|
|
// .net has no built-in read only dictionary
|
|
public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|
{
|
|
private readonly IDictionary<TKey, TValue> dict;
|
|
|
|
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
|
|
{
|
|
dict = dictionary;
|
|
}
|
|
|
|
public void Add(TKey key, TValue value)
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public bool ContainsKey(TKey key)
|
|
{
|
|
return dict.ContainsKey(key);
|
|
}
|
|
|
|
public ICollection<TKey> Keys => dict.Keys;
|
|
|
|
public bool Remove(TKey key)
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
{
|
|
return dict.TryGetValue(key, out value);
|
|
}
|
|
|
|
public ICollection<TValue> Values => dict.Values;
|
|
|
|
public TValue this[TKey key]
|
|
{
|
|
get => dict[key];
|
|
set => throw new InvalidOperationException();
|
|
}
|
|
|
|
public void Add(KeyValuePair<TKey, TValue> item)
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public bool Contains(KeyValuePair<TKey, TValue> item)
|
|
{
|
|
return dict.Contains(item);
|
|
}
|
|
|
|
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
|
{
|
|
dict.CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
public int Count => dict.Count;
|
|
|
|
public bool IsReadOnly => true;
|
|
|
|
public bool Remove(KeyValuePair<TKey, TValue> item)
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
|
{
|
|
return dict.GetEnumerator();
|
|
}
|
|
|
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
|
{
|
|
return ((System.Collections.IEnumerable)dict).GetEnumerator();
|
|
}
|
|
}
|
|
} |