diff --git a/common/hashtable.h b/common/hashtable.h index a53e1b315..5d5c5dd81 100644 --- a/common/hashtable.h +++ b/common/hashtable.h @@ -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 @@ -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; @@ -379,7 +379,7 @@ class OHashTable inline const_iterator end() const { return const_iterator(NOT_FOUND, this); - } + } inline iterator find(const KT& key) { @@ -407,7 +407,7 @@ class OHashTable std::pair insert(const HashPairType& hp) { - unsigned int oldused = mUsed; + unsigned int oldused = mUsed; IndexType bucketnum = insertElement(hp.first, hp.second); return std::pair(iterator(bucketnum, this), mUsed > oldused); } @@ -424,7 +424,7 @@ class OHashTable void erase(iterator it) { - eraseBucket(it.mBucketNum); + eraseBucket(it.mBucketNum); } unsigned int erase(const KT& key) @@ -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: @@ -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) @@ -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;