protected void SetAndEvict(HashBucket <TKey, TValue>[][] tables, TKey key, TValue value, int depth = 0, int tableToSkip = -1) { if (depth >= MAX_CHAIN_DEPTH) { throw new KeyInsertFailedException("Maximum search chain depth reached."); } int tableNumber = PickTableNumberExcept(tableToSkip); HashBucket <TKey, TValue>[] table = tables[tableNumber]; int bucketIndex = HashFunctions[tableNumber](key, table.Length); var bucket = table[bucketIndex]; if (bucket == null) { bucket = new HashBucket <TKey, TValue>(); table[bucketIndex] = bucket; } var newSlot = new HashSlot <TKey, TValue>(key, value); int targetSlotNumber = FindEmptySlot(bucket); if (targetSlotNumber < 0) { // No empty slots. Time to evict someone. targetSlotNumber = PickSlotNumber(bucket); if (targetSlotNumber < 0) { throw new KeyInsertFailedException("Fully locked bucket found. Cannot insert value."); } SetAndEvict(tables, bucket[targetSlotNumber].Key, bucket[targetSlotNumber].Value, depth + 1, tableNumber); } bucket[targetSlotNumber] = newSlot; bucket.Unlock(targetSlotNumber); }
static HashSlot[][] createCascadeHashtable(int size) { var jagged = new HashSlot[size][]; for (int i = 0; i < size; i++) { jagged[i] = new HashSlot[1 << (size - i)]; } return(jagged); }
public void AddToObjectCache(string filename, object obj) { var cache = _cache; var hash = filename.GetHashCode(); var isinserted = false; var maxlevel = _masksize; DateTime oldest = DateTime.MaxValue; int oldestindex = 0; int oldestlevel = 0; for (int level = 0; level < maxlevel - 1; level++) //one day, replace this loop with foreach(getIndexInBuffer()) { var remainingbuffers = maxlevel - level; var mask = collisionBuffersToMask(remainingbuffers); var index = hash & mask; var hashtable = cache[level]; var found = hashtable[index]; if (oldest < found.CreatedDate) { oldest = found.CreatedDate; oldestindex = index; oldestlevel = level; } if (found.Key == null || found.Key == filename) //empty or same filename, so replace (there should only be one with same name, so don't bother checking for duplicate) { hashtable[index] = new HashSlot(filename, new WeakReference(obj), null); isinserted = true; break; } else if (found.Value.Target == null) //everything falling here, has to have key and therefore a WeakReference, so checking if expired. If so, remove prev entry, if one exists { hashtable[index] = new HashSlot(filename, new WeakReference(obj), null); removeStartingAtLevel(filename, level + 1, hash); isinserted = true; break; } hash = hash.GetHashCode(); //re-randomize for next level } if (!isinserted) { //all collision buffers are filled AND active //overwrite the oldest cache[oldestlevel][oldestindex] = new HashSlot(filename, new WeakReference(obj), null); } pinInRotatingMemory(obj); }
public HashSlot <TKey3, TValue3> this[int index] { get { switch (index) { case 0: return(_slot0); case 1: return(_slot1); case 2: return(_slot2); case 3: return(_slot3); case 4: return(_slot4); case 5: return(_slot5); case 6: return(_slot6); default: throw new ArgumentOutOfRangeException(); } } set { switch (index) { case 0: _slot0 = value; Use(0); return; case 1: _slot1 = value; Use(1); return; case 2: _slot2 = value; Use(2); return; case 3: _slot3 = value; Use(3); return; case 4: _slot4 = value; Use(4); return; case 5: _slot5 = value; Use(5); return; case 6: _slot6 = value; Use(6); return; default: throw new ArgumentOutOfRangeException(); } } }
public void SetHashSlot(HashSlot slot) { this.Slot = slot; }
public ListNode(HashSlot slot, ListNode next) { this.NextNode = next; this.Slot = slot; }
public ListNode(HashSlot slot) : this(slot, null) { }