Skip to content

Commit

Permalink
Don't invalide iterators in OHashTable::erase(iterator it1, iterator …
Browse files Browse the repository at this point in the history
…it2)
  • Loading branch information
electricbrass committed Dec 19, 2024
1 parent 85b888d commit 6e08da7
Showing 1 changed file with 29 additions and 8 deletions.
37 changes: 29 additions & 8 deletions common/hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static inline unsigned int __hash_cstring(const char* str)
unsigned int val = 0;
while (*str != 0)
val = val * 101 + *str++;
return val;
return val;
}

template <> struct hashfunc<char*>
Expand Down Expand Up @@ -273,7 +273,7 @@ class OHashTable
do {
mBucketNum++;
} while (mBucketNum < mHashTable->mSize && mHashTable->emptyBucket(mBucketNum));

if (mBucketNum >= mHashTable->mSize)
mBucketNum = IHTT::NOT_FOUND;
return *this;
Expand Down Expand Up @@ -379,7 +379,7 @@ class OHashTable
inline const_iterator end() const
{
return const_iterator(NOT_FOUND, this);
}
}

inline iterator find(const KT& key)
{
Expand Down Expand Up @@ -407,7 +407,7 @@ class OHashTable

std::pair<iterator, bool> insert(const HashPairType& hp)
{
unsigned int oldused = mUsed;
unsigned int oldused = mUsed;
IndexType bucketnum = insertElement(hp.first, hp.second);
return std::pair<iterator, bool>(iterator(bucketnum, this), mUsed > oldused);
}
Expand All @@ -424,7 +424,7 @@ class OHashTable

void erase(iterator it)
{
eraseBucket(it.mBucketNum);
eraseBucket(it.mBucketNum);
}

unsigned int erase(const KT& key)
Expand All @@ -440,9 +440,30 @@ class OHashTable
{
while (it1 != it2)
{
eraseBucket(it1.mBucketNum);
mElements[it1.mBucketNum].order = 0;
mElements[it1.mBucketNum].pair = HashPairType();
mUsed--;
++it1;
}
// Rehash all of the non-empty buckets that follow the erased buckets.
IndexType bucketnum = it2.mBucketNum & mSizeMask;
while (!emptyBucket(bucketnum))
{
const KT& key = mElements[bucketnum].pair.first;
unsigned int order = mElements[bucketnum].order;
mElements[bucketnum].order = 0;

IndexType new_bucketnum = findBucket(key);
mElements[new_bucketnum].order = order;

if (new_bucketnum != bucketnum)
{
mElements[new_bucketnum].pair = mElements[bucketnum].pair;
mElements[bucketnum].pair = HashPairType();
}

bucketnum = (bucketnum + 1) & mSizeMask;
}
}

private:
Expand Down Expand Up @@ -507,7 +528,7 @@ class OHashTable

inline IndexType findBucket(const KT& key) const
{
IndexType bucketnum = (mHashFunc(key) * 2654435761u) & mSizeMask;
IndexType bucketnum = (mHashFunc(key) * 2654435761u) & mSizeMask;

// [SL] NOTE: this can loop infinitely if there is no match and the table is full!
while (!emptyBucket(bucketnum) && mElements[bucketnum].pair.first != key)
Expand Down Expand Up @@ -560,7 +581,7 @@ class OHashTable
if (new_bucketnum != bucketnum)
{
mElements[new_bucketnum].pair = mElements[bucketnum].pair;
mElements[bucketnum].pair = HashPairType();
mElements[bucketnum].pair = HashPairType();
}

bucketnum = (bucketnum + 1) & mSizeMask;
Expand Down

0 comments on commit 6e08da7

Please sign in to comment.