private int Find (Statement key) { Slot [] table = this.table; uint size = (uint) table.Length; int h = key.GetHashCode() & Int32.MaxValue; uint indx = (uint)h; uint step = (uint) ((h >> 5)+1) % (size-1)+1; for (uint i = size; i > 0; i--) { indx %= size; Slot entry = table [indx]; if (!entry.used) break; Statement k = entry.key; if ((entry.hashMix & Int32.MaxValue) == h && k == key) { return (int) indx; } if ((entry.hashMix & CHAIN_MARKER) == 0) break; indx += step; } return -1; }
private void PutImpl (Statement key, Object value, bool overwrite) { uint size = (uint)this.table.Length; if (this.inUse >= this.threshold) { this.Rehash (); size = (uint)this.table.Length; } int h = key.GetHashCode() & Int32.MaxValue; uint spot = (uint)h; uint step = (uint) ((spot>>5)+1)% (size-1)+1; Slot [] table = this.table; Slot entry; int freeIndx = -1; for (int i = 0; i < size; i++) { int indx = (int) (spot % size); entry = table [indx]; if (freeIndx == -1 && entry.removed && (entry.hashMix & CHAIN_MARKER) != 0) freeIndx = indx; if (!entry.used || (entry.removed && (entry.hashMix & CHAIN_MARKER) == 0)) { if (freeIndx == -1) freeIndx = indx; break; } if ((entry.hashMix & Int32.MaxValue) == h && key == entry.key) { if (overwrite) { table [indx].value = value; ++this.modificationCount; } else { // Handle Add (): // An entry with the same key already exists in the Hashtable. throw new ArgumentException ( "Key duplication when adding: " + key); } return; } if (freeIndx == -1) { table [indx].hashMix |= CHAIN_MARKER; } spot+= step; } if (freeIndx!= -1) { table [freeIndx].used = true; table [freeIndx].removed = false; table [freeIndx].key = key; table [freeIndx].value = value; table [freeIndx].hashMix |= h; ++this.inUse; ++this.modificationCount; } }
public Object this [Statement key] { get { Slot [] table = this.table; uint size = (uint) table.Length; int h = key.GetHashCode() & Int32.MaxValue; uint indx = (uint)h; uint step = (uint) ((h >> 5)+1) % (size-1)+1; for (uint i = size; i > 0; i--) { indx %= size; Slot entry = table [indx]; if (!entry.used) break; Statement k = entry.key; if ((entry.hashMix & Int32.MaxValue) == h && k == key) { return entry.value; } if ((entry.hashMix & CHAIN_MARKER) == 0) break; indx += step; } return null; } set { PutImpl (key, value, true); } }