private void Resize(int newSize) { // Hash table size needs to be prime. newSize = PrimeHelper.NextPrime(newSize); var newTable = new int[newSize]; var newSlots = new Slot[newSize]; // Copy current slots. Array.Copy(_slots, 0, newSlots, 0, _touchedSlots); // Update hash table and rebuild chains. for (int slotIndex = 0; slotIndex < _touchedSlots; slotIndex++) { int hashCode = GetHashCode(newSlots[slotIndex].ObjectA, newSlots[slotIndex].ObjectB); int tableIndex = hashCode % newSize; newSlots[slotIndex].Next = newTable[tableIndex] - 1; newTable[tableIndex] = slotIndex + 1; } _table = newTable; _slots = newSlots; if (_used != null) { var newUsed = new bool[newSize]; Array.Copy(_used, 0, newUsed, 0, _touchedSlots); _used = newUsed; } }
public void TestNextPrime() { var input = new[] { 18, 13, 68, 99, 93, 34, 11, 47, 64, 10, 809, 3420, 9391, 8999, 5154, 8934, 5416, 5669, 2755, 3159, 285080, 727881, 846232, 665370, 153194, 157833, 585896, 914054, 505284, 333258, 49086597, 78119724, 76928802, 23260170, 1955743, 39360664, 10885879, 30169506, 65889970, 95425647, 179424551, 179424571, 179424577, 179424601, 179424611, 179424617, 179424629, 179424667, 179424671, 179424673, 1683899352, 883641873, 114883641, 1000000007, 1000000009, 1000000021, 1000000033, 1000000087, 1000000093 }; var output = new[] { 19, 17, 71, 101, 97, 37, 13, 53, 67, 11, 811, 3433, 9397, 9001, 5167, 8941, 5417, 5683, 2767, 3163, 285091, 727891, 846233, 665381, 153247, 157837, 585899, 914117, 505301, 333269, 49086613, 78119749, 76928807, 23260187, 1955747, 39360683, 10885891, 30169523, 65889997, 95425663, 179424571, 179424577, 179424601, 179424611, 179424617, 179424629, 179424667, 179424671, 179424673, 179424691, 1683899359, 883641893, 114883661, 1000000009, 1000000021, 1000000033, 1000000087, 1000000093, 1000000097 }; Assert.AreEqual(input.Length, output.Length, "setup"); for (var index = 0; index < output.Length; index++) { Assert.AreEqual(output[index], PrimeHelper.NextPrime(input[index])); Assert.IsTrue(PrimeHelper.IsPrime(output[index])); } }
/// <summary> /// Sets the capacity of the <see cref="HashSetEx{T}"/> to a value suitable for the current /// number of elements in the set. /// </summary> /// <remarks> /// <para> /// This method can be used to minimize a collection's memory overhead if no new elements will /// be added to the collection. /// </para> /// <para> /// This method is an O(n) operation, where n is <see cref="Count"/>. /// </para> /// <para> /// To reset a <see cref="HashSetEx{T}"/> to its initial state, call the <see cref="Clear"/> /// method before calling <see cref="TrimExcess"/> method. Trimming an empty /// <see cref="HashSetEx{T}"/> sets the capacity of the <see cref="HashSetEx{T}"/> to the /// default capacity. /// </para> /// </remarks> public void TrimExcess() { // Similar to Resize(), except that TrimExcess() compacts the items and clears // the free list! int newSize = PrimeHelper.NextPrime((_count > 0) ? _count : InitialSize); int[] newTable = new int[newSize]; var newSlots = new Slot[newSize]; // Insert items in new hash table and slots (without recomputing the hash code). int newIndex = 0; for (int oldIndex = 0; oldIndex < _touchedSlots; oldIndex++) { if (_slots[oldIndex].HashCode >= 0) { newSlots[newIndex].HashCode = _slots[oldIndex].HashCode; newSlots[newIndex].Item = _slots[oldIndex].Item; int tableIndex = newSlots[newIndex].HashCode % newSize; newSlots[newIndex].Next = newTable[tableIndex] - 1; newTable[tableIndex] = newIndex + 1; newIndex++; } } _table = newTable; _slots = newSlots; _touchedSlots = newIndex; _freeList = -1; _version++; }
private void Resize(int newSize) { // Similar to TrimAccess(), except that Resize() does not compact the items. // The free list remains! // Hash table size needs to be prime. newSize = PrimeHelper.NextPrime(newSize); var newTable = new int[newSize]; var newSlots = new Slot[newSize]; // Copy current slots. Array.Copy(_slots, 0, newSlots, 0, _touchedSlots); // Update hash table and rebuild chains. for (int slotIndex = 0; slotIndex < _touchedSlots; slotIndex++) { int tableIndex = newSlots[slotIndex].HashCode % newSize; newSlots[slotIndex].Next = newTable[tableIndex] - 1; newTable[tableIndex] = slotIndex + 1; } _table = newTable; _slots = newSlots; }
/// <summary> /// Initializes a new instance of the <see cref="SynchronizedHashtable{TKey,TValue}"/> class. /// </summary> /// <param name="capacity">The number of buckets in the hash table.</param> /// <remarks> /// For efficiency the <paramref name="capacity"/> is automatically incremented to the next /// prime number. /// </remarks> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="capacity"/> is less than 1. /// </exception> public SynchronizedHashtable(int capacity) { if (capacity < 1) throw new ArgumentOutOfRangeException("capacity", "The initial capacity must be greater than 0."); capacity = PrimeHelper.NextPrime(capacity); _buckets = new Node[capacity]; }
private void Initialize(int capacity) { capacity = PrimeHelper.NextPrime(capacity); _table = new int[capacity]; _slots = new Slot[capacity]; _touchedSlots = 0; _freeList = -1; _count = 0; _version = 0; }
public void TestPrimeBounds() { // 2147483629 is tha last prime below int.MaxValue Assert.AreEqual(2, PrimeHelper.NextPrime(-1)); Assert.AreEqual(3, PrimeHelper.NextPrime(2)); Assert.Throws <OverflowException>(() => PrimeHelper.NextPrime(2147483629)); // 2147483629 is tha last prime below int.MaxValue Assert.AreEqual(2, PrimeHelper.ToPrime(-1)); Assert.AreEqual(2, PrimeHelper.ToPrime(2)); Assert.AreEqual(2147483629, PrimeHelper.ToPrime(2147483629)); }
private void Initialize(int capacity, IEqualityComparer<T> comparer) { capacity = PrimeHelper.NextPrime(capacity); _table = new int[capacity]; _slots = new Slot[capacity]; _touchedSlots = 0; _freeList = -1; _count = 0; _comparer = comparer ?? EqualityComparer<T>.Default; _version = 0; }
public void NextPrimesTest() { for (int n = 1; n < int.MaxValue / 2; n <<= 1) { int prime = PrimeHelper.NextPrime(n); Assert.GreaterOrEqual(prime, n); Assert.IsTrue(PrimeHelper.IsPrime(prime)); if (n > 1) { // Prime number should be close to actual number. Assert.LessOrEqual(prime, (int)(n * 1.5)); } } }