void cache_t::reallocate(mask_t oldCapacity, mask_t newCapacity) { bucket_t *newBuckets = allocateBuckets(newCapacity); assert(newCapacity > 0); assert((uintptr_t)(mask_t)(newCapacity) == newCapacity); setBucketsAndMask(newBuckets, newCapacity ); }
void BasicHashtableImpl::rehash(size_t minimumCapacity, float loadFactor) { if (minimumCapacity < mSize) { minimumCapacity = mSize; } size_t newBucketCount, newCapacity; determineCapacity(minimumCapacity, loadFactor, &newBucketCount, &newCapacity); if (newBucketCount != mBucketCount || newCapacity != mCapacity) { if (mBuckets) { void* newBuckets; if (mSize) { newBuckets = allocateBuckets(newBucketCount); for (size_t i = 0; i < mBucketCount; i++) { const Bucket& fromBucket = bucketAt(mBuckets, i); if (fromBucket.cookie & Bucket::PRESENT) { hash_t hash = fromBucket.cookie & Bucket::HASH_MASK; size_t index = chainStart(hash, newBucketCount); Bucket* toBucket = &bucketAt(newBuckets, size_t(index)); if (toBucket->cookie & Bucket::PRESENT) { size_t inc = chainIncrement(hash, newBucketCount); do { toBucket->cookie |= Bucket::COLLISION; index = chainSeek(index, inc, newBucketCount); toBucket = &bucketAt(newBuckets, size_t(index)); } while (toBucket->cookie & Bucket::PRESENT); } toBucket->cookie = Bucket::PRESENT | hash; initializeBucketEntry(*toBucket, fromBucket.entry); } } } else { newBuckets = NULL; } releaseBuckets(mBuckets, mBucketCount); mBuckets = newBuckets; mFilledBuckets = mSize; } mBucketCount = newBucketCount; mCapacity = newCapacity; } mLoadFactor = loadFactor; }