Skip to content

Commit

Permalink
Fix potential concurrency bug in PairHashSet.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
notgiven688 committed Dec 29, 2024
1 parent bc73f2e commit 68474cc
Showing 1 changed file with 11 additions and 11 deletions.
22 changes: 11 additions & 11 deletions src/Jitter2/Collision/PairHashSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ public void Reset()

public Pair[] Slots = Array.Empty<Pair>();

private int modder = 1;

// 16384*8/1024 KB = 128 KB
public const int MinimumSize = 16384;
public const int TrimFactor = 8;
Expand Down Expand Up @@ -152,8 +150,6 @@ private void Resize(int size)

Interlocked.MemoryBarrier();

modder = size - 1;

for (int i = 0; i < tmp.Length; i++)
{
Pair pair = tmp[i];
Expand Down Expand Up @@ -189,7 +185,7 @@ public bool Add(Pair pair)
{
while (true)
{
int hash_i = FindSlot(hash, pair.ID);
int hash_i = FindSlot(originalSlots, hash, pair.ID);
Pair* slotPtr = &slotsPtr[hash_i];

if (slotPtr->ID == pair.ID)
Expand Down Expand Up @@ -232,19 +228,23 @@ public bool Add(Pair pair)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int FindSlot(int hash, long id)
private int FindSlot(Pair[] slots, int hash, long id)
{
hash &= modder;
int lmodder = slots.Length - 1;

hash &= lmodder;

while (true)
{
if (Slots[hash].ID == 0 || Slots[hash].ID == id) return hash;
hash = (hash + 1) & modder;
hash = (hash + 1) & lmodder;
}
}

public bool Remove(int slot)
{
int lmodder = Slots.Length - 1;

if (Slots[slot].ID == 0)
{
return false;
Expand All @@ -254,14 +254,14 @@ public bool Remove(int slot)

while (true)
{
hash_j = (hash_j + 1) & modder;
hash_j = (hash_j + 1) & lmodder;

if (Slots[hash_j].ID == 0)
{
break;
}

int hash_k = Slots[hash_j].GetHash() & modder;
int hash_k = Slots[hash_j].GetHash() & lmodder;

// https://en.wikipedia.org/wiki/Open_addressing
if ((hash_j > slot && (hash_k <= slot || hash_k > hash_j)) ||
Expand All @@ -286,7 +286,7 @@ public bool Remove(int slot)
public bool Remove(Pair pair)
{
int hash = pair.GetHash();
int hash_i = FindSlot(hash, pair.ID);
int hash_i = FindSlot(Slots, hash, pair.ID);
return Remove(hash_i);
}

Expand Down

0 comments on commit 68474cc

Please sign in to comment.