private int EnsureIndex(object key)
{
int hash = key.GetHashCode();
int index = -1;
int firstDeleted = -1;
if (keys != null)
{
int fraction = hash * A;
index = (int)(((uint)fraction) >> (32 - power));
object test = keys[index];
if (test != null)
{
int N = 1 << power;
if (test == key || (values[N + index] == hash && test.Equals(key)))
{
return index;
}
if (test == DELETED)
{
firstDeleted = index;
}
// Search in table after first failed attempt
int mask = N - 1;
int step = TableLookupStep(fraction, mask, power);
int n = 0;
for (; ; )
{
index = (index + step) & mask;
test = keys[index];
if (test == null)
{
break;
}
if (test == key || (values[N + index] == hash && test.Equals(key)))
{
return index;
}
if (test == DELETED && firstDeleted < 0)
{
firstDeleted = index;
}
}
}
}
// Inserting of new key
if (check && keys != null && keys[index] != null)
{
Kit.CodeBug();
}
if (firstDeleted >= 0)
{
index = firstDeleted;
}
else
{
// Need to consume empty entry: check occupation level
if (keys == null || occupiedCount * 4 >= (1 << power) * 3)
{
// Too litle unused entries: rehash
RehashTable();
return InsertNewKey(key, hash);
}
++occupiedCount;
}
keys[index] = key;
values[(1 << power) + index] = hash;
++keyCount;
return index;
}