Skip to content

Instantly share code, notes, and snippets.

@mjs3339
Last active February 19, 2019 23:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjs3339/f8cba37c33b87d9653491ec34bff1d94 to your computer and use it in GitHub Desktop.
Save mjs3339/f8cba37c33b87d9653491ec34bff1d94 to your computer and use it in GitHub Desktop.
C# A Tiny Dictionary...
[DebuggerTypeProxy(typeof(HashSetDebugViewInt<>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class TinyDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
public TinySet<TKey> Keys;
public int Resizes;
public TValue[] Values;
public TinyDictionary() : this(1024, EqualityComparer<TKey>.Default)
{
}
public TinyDictionary(int size) : this(size, EqualityComparer<TKey>.Default)
{
}
public TinyDictionary(int size, IEqualityComparer<TKey> comparer)
{
if(comparer == null) comparer = EqualityComparer<TKey>.Default;
Keys = new TinySet<TKey>(size);
Values = new TValue[size];
Keys.Comparer = comparer;
}
public TinyDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer = null)
{
if(comparer == null) comparer = EqualityComparer<TKey>.Default;
Keys.Comparer = comparer;
foreach(var kp in collection)
Add(kp.Key, kp.Value);
}
public int Count => Keys.Count;
public TValue this[TKey key]
{
get
{
var pos = Keys.FindEntry(key);
return pos == -1 ? default : Values[pos];
}
set => Add(key, value);
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(this);
}
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
public bool Add(TKey key, TValue value)
{
if(!Keys.Insert(key, true))
{
if(Values.Length != Keys.Slots.Length)
{
var nValues = new TValue[Keys.Slots.Length];
Array.Copy(Values, nValues, Values.Length);
Values = nValues;
Resizes++;
}
Values[Keys.Position] = value;
return false;
}
Values[Keys.Position] = value;
return true;
}
public bool ContainsKey(TKey key)
{
return Keys.FindEntry(key) != -1;
}
public int FindKeyIndex(TKey key)
{
return Keys.FindEntry(key);
}
[Serializable]
public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDictionaryEnumerator
{
private readonly TinyDictionary<TKey, TValue> dictionary;
private int index;
internal Enumerator(TinyDictionary<TKey, TValue> dictionary)
{
this.dictionary = dictionary;
index = 0;
Current = new KeyValuePair<TKey, TValue>();
}
public bool MoveNext()
{
if((uint) index < (uint) dictionary.Keys.Count)
{
Current = new KeyValuePair<TKey, TValue>(dictionary.Keys.Slots[index].Value, dictionary.Values[index]);
index++;
return true;
}
index = dictionary.Keys.Count + 1;
Current = new KeyValuePair<TKey, TValue>();
return false;
}
public KeyValuePair<TKey, TValue> Current{get; private set;}
public void Dispose()
{
}
object IEnumerator.Current
{
get
{
if(index == 0 || index == dictionary.Keys.Count + 1)
throw new Exception("Invalid Index.");
return new KeyValuePair<TKey, TValue>(Current.Key, Current.Value);
}
}
void IEnumerator.Reset()
{
index = 0;
Current = new KeyValuePair<TKey, TValue>();
}
DictionaryEntry IDictionaryEnumerator.Entry
{
get
{
if(index == 0 || index == dictionary.Keys.Count + 1)
throw new Exception("Invalid Index.");
return new DictionaryEntry(Current.Key, Current.Value);
}
}
object IDictionaryEnumerator.Key
{
get
{
if(index == 0 || index == dictionary.Keys.Count + 1)
throw new Exception("Invalid Index.");
return Current.Key;
}
}
object IDictionaryEnumerator.Value
{
get
{
if(index == 0 || index == dictionary.Keys.Count + 1)
throw new Exception("Invalid Index.");
return Current.Value;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment