Last active
August 29, 2015 13:56
-
-
Save fekberg/8968804 to your computer and use it in GitHub Desktop.
Dictionary implementation
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
void Main() | |
{ | |
var values = new List<string>(); | |
var dict = new FancyDictionary<string, string>(); | |
var insertWatch = new Stopwatch(); | |
for(int i = 0; i < 3000; i++) | |
{ | |
var entry = Guid.NewGuid().ToString(); | |
values.Add(entry); | |
insertWatch.Start(); | |
dict.Add(entry, entry); | |
insertWatch.Stop(); | |
} | |
Console.WriteLine ("Average insert time: {0} ms", (double)insertWatch.ElapsedMilliseconds / (double)values.Count); | |
Console.WriteLine ("Longest linear search {0}", dict.GetLongestList()); | |
Console.WriteLine ("Dictionary keys {0}", dict.CountHashKeys()); | |
int missingKeys = 0; | |
var watch = new Stopwatch(); | |
foreach(var value in values) | |
{ | |
watch.Start(); | |
if(!dict.ContainsKey(value)) missingKeys ++; | |
watch.Stop(); | |
} | |
Console.WriteLine ("Missing elements: {0}", missingKeys); | |
Console.WriteLine ("Average access time: {0} ms", (double)watch.ElapsedMilliseconds / (double)values.Count); | |
} | |
class FancyDictionary<K, T> | |
{ | |
private struct FancyKeyValuePair<K, T> | |
{ | |
public K Key { get; set; } | |
public T Value { get; set; } | |
} | |
private IList<FancyKeyValuePair<K, T>>[] table; | |
private int length = 2; | |
private int count; | |
public FancyDictionary() | |
{ | |
table = new List<FancyKeyValuePair<K, T>>[length]; | |
} | |
private int Hash(K key) | |
{ | |
return Math.Abs(key.GetHashCode()) % length; | |
} | |
private void IncreaseTable() | |
{ | |
length = table.Length * 2; | |
var newTable = new List<FancyKeyValuePair<K, T>>[length]; | |
foreach(var row in table) | |
{ | |
if(row == null) continue; | |
foreach(var cell in row) | |
{ | |
var newHash = Hash(cell.Key); | |
if(newTable[newHash] == null) newTable[newHash] = new List<FancyKeyValuePair<K, T>>(); | |
newTable[newHash].Add(new FancyKeyValuePair<K, T>{Key = cell.Key, Value = cell.Value}); | |
} | |
} | |
table = newTable; | |
} | |
public int GetLongestList() | |
{ | |
var largest = 0; | |
foreach(var item in table) | |
{ | |
if(item != null && item.Count > largest) largest = item.Count; | |
} | |
return largest; | |
} | |
public int CountHashKeys() | |
{ | |
var keys = 0; | |
foreach(var item in table) | |
{ | |
if(item != null) keys++; | |
} | |
return keys; | |
} | |
public bool ContainsKey(K key) | |
{ | |
var hash = Hash(key); | |
return table[hash] != null && table[hash].Any(); | |
} | |
public object this[K key] | |
{ | |
get | |
{ | |
var hash = Hash(key); | |
var row = table[hash]; | |
if(row == null) return null; | |
foreach(var cell in row) | |
{ | |
if(cell.Key.Equals(key)) return cell.Value; | |
} | |
return null; | |
} | |
} | |
public void Add(K key, T value) | |
{ | |
count += 1; | |
if(count > table.Length) IncreaseTable(); | |
var hash = Hash(key); | |
if(table[hash] == null) | |
{ | |
table[hash] = new List<FancyKeyValuePair<K, T>>(); | |
} | |
table[hash].Add(new FancyKeyValuePair<K, T>{Key = key, Value = value}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Looking forward to using something familiar in my programs. Thank you Filip!