Last active
November 25, 2018 08:21
-
-
Save mjs3339/eceab6a2b5b633c10f4e567f93be5f98 to your computer and use it in GitHub Desktop.
C# BigDictionary Class Greater than 2GB
This file contains hidden or 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 BigDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> | |
{ | |
public BigSet<TKey> Keys; | |
public int Resizes; | |
public BigArray<TValue> Values; | |
public BigDictionary() : this(BigArray<TKey>.Granularity, new BigComparer<TKey>()) | |
{ | |
} | |
public BigDictionary(ulong size) : this(size, new BigComparer<TKey>()) | |
{ | |
} | |
public BigDictionary(ulong size, IBigEqualityComparer<TKey> comparer) | |
{ | |
if(comparer == null) comparer = new BigComparer<TKey>(); | |
Keys = new BigSet<TKey>(size); | |
Values = new BigArray<TValue>(size); | |
Keys._comparer = comparer; | |
} | |
public BigDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IBigEqualityComparer<TKey> comparer = null) | |
{ | |
if(comparer == null) comparer = new BigComparer<TKey>(); | |
Keys._comparer = comparer; | |
foreach(var kp in collection) | |
Add(kp.Key, kp.Value); | |
} | |
public ulong Count => Keys.Count; | |
public TValue this[TKey key] | |
{ | |
get => Keys.Insert(key, false) ? Values[Keys.Position] : default; | |
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) | |
{ | |
Values = Values.Copy(Keys._slots.Length); | |
Resizes++; | |
} | |
Values[Keys.Position] = value; | |
return false; | |
} | |
Values[Keys.Position] = value; | |
return true; | |
} | |
public bool ContainsKey(TKey key) | |
{ | |
return Keys.Insert(key, false); | |
} | |
[Serializable] | |
public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDictionaryEnumerator | |
{ | |
private readonly BigDictionary<TKey, TValue> dictionary; | |
private ulong index; | |
internal Enumerator(BigDictionary<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