Last active
August 29, 2015 14:18
-
-
Save airbreather/afc66fed283b23e43ffa to your computer and use it in GitHub Desktop.
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
using System; | |
using System.Collections.Generic; | |
namespace UrbanScience | |
{ | |
public struct Int32Set | |
{ | |
private readonly int[] buckets; | |
private readonly Slot[] slots; | |
public Int32Set(IReadOnlyList<int> collection) | |
{ | |
////if (collection == null) | |
////{ | |
//// throw new ArgumentNullException("collection"); | |
////} | |
int count = collection.Count; | |
int size = GetPrime(count); | |
this.buckets = new int[size]; | |
this.slots = new Slot[size]; | |
for (int i = 0; i < count; i++) | |
{ | |
int value = collection[i]; | |
int bucket = value % this.buckets.Length; | |
this.slots[i].value = value; | |
this.slots[i].next = this.buckets[bucket] - 1; | |
this.buckets[bucket] = i + 1; | |
} | |
} | |
public bool Contains(int item) | |
{ | |
////if (this.buckets == null) | |
////{ | |
//// return false; | |
////} | |
for (int i = this.buckets[item % this.buckets.Length] - 1; i >= 0; i = this.slots[i].next) | |
{ | |
if (this.slots[i].value == item) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
private struct Slot | |
{ | |
internal int value; | |
internal int next; | |
} | |
// https://github.com/Microsoft/referencesource/blob/9da503f9ef21e8d1f2905c78d4e3e5cbb3d6f85a/mscorlib/system/collections/hashtable.cs#L1691-L1878 | |
#region HashHelpers | |
private static readonly int[] Primes = { | |
3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, | |
1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, | |
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, | |
187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, | |
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369}; | |
private static int GetPrime(int min) | |
{ | |
for (int i = 0; i < Primes.Length; i++) | |
{ | |
int prime = Primes[i]; | |
if (prime >= min) | |
{ | |
return prime; | |
} | |
} | |
for (int i = (min | 1); i < Int32.MaxValue; i += 2) | |
{ | |
// The % 101 in the base version strictly benefits Hashtable. | |
////if (IsPrime(i) && ((i - 1) % 101 != 0)) | |
if (IsPrime(i)) | |
{ | |
return i; | |
} | |
} | |
return min; | |
} | |
private static bool IsPrime(int candidate) | |
{ | |
if ((candidate & 1) == 0) | |
{ | |
return candidate == 2; | |
} | |
int limit = (int)Math.Sqrt(candidate); | |
for (int divisor = 3; divisor <= limit; divisor += 2) | |
{ | |
if ((candidate % divisor) == 0) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment