Skip to content

Instantly share code, notes, and snippets.

@airbreather
Last active August 29, 2015 14:18
Show Gist options
  • Save airbreather/afc66fed283b23e43ffa to your computer and use it in GitHub Desktop.
Save airbreather/afc66fed283b23e43ffa to your computer and use it in GitHub Desktop.
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