in FixAntenna/NetCore/Message/FieldIndex.cs [611:701]
private void RemoveFromHashtblInternal(int tagId, int indexOffset)
{
var secondOccuranceIndex = GetTagOccurrenceIndex(tagId, 2);
var hashIndex = FindElementInHashTbl(tagId);
var needToRehash = false;
if (secondOccuranceIndex != IndexedStorage.NotFound)
{
Hashtbl[hashIndex + HashtblIndexEntry] = secondOccuranceIndex * ItemsPerField;
// adjust mapping into index array for the index elements greater than the removed
for (var j = 0; j < Hashtbl.Length; j += ItemsInHashentry)
{
if (Hashtbl[j + HashtblTagEntry] != 0 && Hashtbl[j + HashtblIndexEntry] > indexOffset)
{
Hashtbl[j + HashtblIndexEntry] -= ItemsPerField;
}
}
return;
}
HashtblElems--;
if (!needToRehash)
{
// check next element - if it have same hashCode - we need rehash
var size = Hashtbl.Length / ItemsInHashentry;
var deleted = hashIndex / ItemsInHashentry;
var next = deleted + 1;
if (next >= size)
{
next = 0;
}
if (Hashtbl[next * ItemsInHashentry] != 0)
{
needToRehash = true;
}
// // see if this created a gap that we potentially need to close
// // consider the sequence of elements: 0, x1, x2, [gap: deleted element], x3, x4, 0
// // gap is created if both x2 and x3 were present (not 0)
//
// int size = hashtbl.length / ITEMS_IN_HASHENTRY;
// int deleted = hashIndex / ITEMS_IN_HASHENTRY;
// int x2 = mod((deleted - 1), size);
// int x3 = mod((deleted + 1), size);
//
// if (hashtbl[x2 * ITEMS_IN_HASHENTRY] != 0 && hashtbl[x3 * ITEMS_IN_HASHENTRY] != 0) {
// // yes, we created a gap
//
// // TBD!
// // An optimal solution would be: to make sure the element addressing is correct in the range from x1 to x4
// // and re-hash elements in the range from x4 to x1 (starting from x4 and going to x1)
//
// // ... for now we're going just re-hash the whole table, which is less optimal
//
// needToRehash = true;
// }
}
if (needToRehash)
{
ClearHashTbl(Hashtbl);
// rehash the table
for (var i = 0; i < _fieldCount * ItemsPerField; i += ItemsPerField)
{
var tag = _index[i + Tag];
// skip tag that we removing
if (tag != tagId)
{
AddToHashTbl(Hashtbl, tag, i, 0);
}
}
}
else
{
// remove a single element
// erase the element
Hashtbl[hashIndex + HashtblTagEntry] = 0;
}
// adjust mapping into index array for the index elements greater than the removed
for (var j = 0; j < Hashtbl.Length; j += ItemsInHashentry)
{
if (Hashtbl[j + HashtblTagEntry] != 0 && Hashtbl[j + HashtblIndexEntry] > indexOffset)
{
Hashtbl[j + HashtblIndexEntry] -= ItemsPerField;
}
}
}