NameTable
class NameTable
namespace Microsoft.CSharp.RuntimeBinder.Syntax
{
internal class NameTable
{
private class Entry
{
internal readonly Name name;
internal readonly int hashCode;
internal Entry next;
internal Entry(Name name, int hashCode, Entry next)
{
this.name = name;
this.hashCode = hashCode;
this.next = next;
}
}
private Entry[] _entries;
private int _count;
private int _mask;
private int _hashCodeRandomizer;
internal NameTable()
{
_mask = 31;
_entries = new Entry[_mask + 1];
_hashCodeRandomizer = 0;
}
public Name Add(string key)
{
int num = ComputeHashCode(key);
for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.next) {
if (entry.hashCode == num && entry.name.Text.Equals(key))
return entry.name;
}
return AddEntry(new Name(key), num);
}
internal void Add(Name name)
{
int num = ComputeHashCode(name.Text);
for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.next) {
if (entry.hashCode == num && entry.name.Text.Equals(name.Text))
throw Error.InternalCompilerError();
}
AddEntry(name, num);
}
public Name Lookup(string key)
{
int num = ComputeHashCode(key);
for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.next) {
if (entry.hashCode == num && entry.name.Text.Equals(key))
return entry.name;
}
return null;
}
private int ComputeHashCode(string key)
{
int length = key.Length;
int num = length + _hashCodeRandomizer;
for (int i = 0; i < key.Length; i++) {
num += ((num << 7) ^ key[i]);
}
num -= num >> 17;
num -= num >> 11;
return num - (num >> 5);
}
private Name AddEntry(Name name, int hashCode)
{
int num = hashCode & _mask;
Entry entry = new Entry(name, hashCode, _entries[num]);
_entries[num] = entry;
if (_count++ == _mask)
Grow();
return entry.name;
}
private void Grow()
{
int num = _mask * 2 + 1;
Entry[] entries = _entries;
Entry[] array = new Entry[num + 1];
for (int i = 0; i < entries.Length; i++) {
Entry next;
for (Entry entry = entries[i]; entry != null; entry = next) {
int num2 = entry.hashCode & num;
next = entry.next;
entry.next = array[num2];
array[num2] = entry;
}
}
_entries = array;
_mask = num;
}
}
}