/// <summary> /// CONSTRUCTOR /// </summary> public CuckooHashTable() { _size = 0; _numberOfRehashes = 0; _randomizer = new Random(); _collection = new CHashEntry <TKey, TValue> [DEFAULT_CAPACITY]; _universalHashingFamily = new UniversalHashingFamily(NUMBER_OF_HASH_FUNCTIONS); }
/// <summary> /// Inserts a key-value pair into hash table. /// </summary> private void _insertHelper(TKey key, TValue value) { int COUNT_LIMIT = 100; var newEntry = new CHashEntry <TKey, TValue>(key, value, isActive: true); while (true) { int position, lastPosition = -1; for (int count = 0; count < COUNT_LIMIT; count++) { // The hash functions numbers are indexed from 1 not zero for (int i = 1; i <= NUMBER_OF_HASH_FUNCTIONS; i++) { position = _cuckooHash(key, i); if (!_isActive(position)) { _collection[position] = newEntry; // Increment size ++_size; return; } } // Eviction strategy: // No available spot was found. Choose a random one. int j = 0; do { position = _cuckooHash(key, _randomizer.Next(1, NUMBER_OF_HASH_FUNCTIONS)); } while (position == lastPosition && j++ < NUMBER_OF_HASH_FUNCTIONS); // SWAP ENTRY lastPosition = position; var temp = _collection[position]; _collection[position] = newEntry; newEntry = temp; }//end-for if (++_numberOfRehashes > ALLOWED_REHASHES) { // Expand the table. _expandCapacity(_collection.Length + 1); // Reset number of rehashes. _numberOfRehashes = 0; } else { // Rehash the table with the same current size. _rehash(); } }//end-while }