* ExecHashIncreaseNumBuckets * increase the original number of buckets in order to reduce * number of tuples per bucket */
| 1708 | * number of tuples per bucket |
| 1709 | */ |
| 1710 | static void |
| 1711 | ExecHashIncreaseNumBuckets(HashJoinTable hashtable) |
| 1712 | { |
| 1713 | HashMemoryChunk chunk; |
| 1714 | |
| 1715 | /* do nothing if not an increase (it's called increase for a reason) */ |
| 1716 | if (hashtable->nbuckets >= hashtable->nbuckets_optimal) |
| 1717 | return; |
| 1718 | |
| 1719 | #ifdef HJDEBUG |
| 1720 | printf("Hashjoin %p: increasing nbuckets %d => %d\n", |
| 1721 | hashtable, hashtable->nbuckets, hashtable->nbuckets_optimal); |
| 1722 | #endif |
| 1723 | |
| 1724 | hashtable->nbuckets = hashtable->nbuckets_optimal; |
| 1725 | hashtable->log2_nbuckets = hashtable->log2_nbuckets_optimal; |
| 1726 | |
| 1727 | Assert(hashtable->nbuckets > 1); |
| 1728 | Assert(hashtable->nbuckets <= (INT_MAX / 2)); |
| 1729 | Assert(hashtable->nbuckets == (1 << hashtable->log2_nbuckets)); |
| 1730 | |
| 1731 | /* |
| 1732 | * Just reallocate the proper number of buckets - we don't need to walk |
| 1733 | * through them - we can walk the dense-allocated chunks (just like in |
| 1734 | * ExecHashIncreaseNumBatches, but without all the copying into new |
| 1735 | * chunks) |
| 1736 | */ |
| 1737 | hashtable->buckets.unshared = |
| 1738 | (HashJoinTuple *) repalloc(hashtable->buckets.unshared, |
| 1739 | hashtable->nbuckets * sizeof(HashJoinTuple)); |
| 1740 | |
| 1741 | memset(hashtable->buckets.unshared, 0, |
| 1742 | hashtable->nbuckets * sizeof(HashJoinTuple)); |
| 1743 | |
| 1744 | /* scan through all tuples in all chunks to rebuild the hash table */ |
| 1745 | for (chunk = hashtable->chunks; chunk != NULL; chunk = chunk->next.unshared) |
| 1746 | { |
| 1747 | /* process all tuples stored in this chunk */ |
| 1748 | size_t idx = 0; |
| 1749 | |
| 1750 | while (idx < chunk->used) |
| 1751 | { |
| 1752 | HashJoinTuple hashTuple = (HashJoinTuple) (HASH_CHUNK_DATA(chunk) + idx); |
| 1753 | int bucketno; |
| 1754 | int batchno; |
| 1755 | |
| 1756 | ExecHashGetBucketAndBatch(hashtable, hashTuple->hashvalue, |
| 1757 | &bucketno, &batchno); |
| 1758 | |
| 1759 | /* add the tuple to the proper bucket */ |
| 1760 | hashTuple->next.unshared = hashtable->buckets.unshared[bucketno]; |
| 1761 | hashtable->buckets.unshared[bucketno] = hashTuple; |
| 1762 | |
| 1763 | /* advance index past the tuple */ |
| 1764 | idx += MAXALIGN(HJTUPLE_OVERHEAD + |
| 1765 | HJTUPLE_MINTUPLE(hashTuple)->t_len); |
| 1766 | } |
| 1767 |
no test coverage detected