Last active
February 19, 2019 23:16
-
-
Save mjs3339/f8cba37c33b87d9653491ec34bff1d94 to your computer and use it in GitHub Desktop.
C# A Tiny Dictionary...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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