| 398 | } |
| 399 | |
| 400 | void Compact() |
| 401 | { |
| 402 | if (_elementsCount == 0) |
| 403 | { |
| 404 | // Fast path if it's empty |
| 405 | BucketType* data = _allocation.Get(); |
| 406 | for (int32 i = 0; i < _size; ++i) |
| 407 | data[i]._state = HashSetBucketState::Empty; |
| 408 | } |
| 409 | else |
| 410 | { |
| 411 | // Rebuild entire table completely |
| 412 | const int32 elementsCount = _elementsCount; |
| 413 | const int32 oldSize = _size; |
| 414 | AllocationData oldAllocation; |
| 415 | AllocationUtils::MoveToEmpty<BucketType, AllocationType>(oldAllocation, _allocation, oldSize, oldSize); |
| 416 | _allocation.Allocate(_size); |
| 417 | BucketType* data = _allocation.Get(); |
| 418 | for (int32 i = 0; i < oldSize; ++i) |
| 419 | data[i]._state = HashSetBucketState::Empty; |
| 420 | BucketType* oldData = oldAllocation.Get(); |
| 421 | FindPositionResult pos; |
| 422 | for (int32 i = 0; i < oldSize; ++i) |
| 423 | { |
| 424 | BucketType& oldBucket = oldData[i]; |
| 425 | if (oldBucket.IsOccupied()) |
| 426 | { |
| 427 | FindPosition(oldBucket.GetKey(), pos); |
| 428 | if (pos.FreeSlotIndex == -1) |
| 429 | { |
| 430 | // Grow and retry to handle pathological cases (eg. heavy collisions) |
| 431 | EnsureCapacity(_size + 1, true); |
| 432 | FindPosition(oldBucket.GetKey(), pos); |
| 433 | ASSERT(pos.FreeSlotIndex != -1); |
| 434 | } |
| 435 | BucketType& bucket = _allocation.Get()[pos.FreeSlotIndex]; |
| 436 | bucket = MoveTemp(oldBucket); |
| 437 | } |
| 438 | } |
| 439 | for (int32 i = 0; i < oldSize; ++i) |
| 440 | oldData[i].Free(); |
| 441 | _elementsCount = elementsCount; |
| 442 | } |
| 443 | _deletedCount = 0; |
| 444 | } |
| 445 | }; |
nothing calls this directly
no test coverage detected