diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c index 0e0f393..011f7e4 100644 --- a/src/backend/access/hash/hashsort.c +++ b/src/backend/access/hash/hashsort.c @@ -37,7 +37,7 @@ struct HSpool { Tuplesortstate *sortstate; /* state data for tuplesort.c */ Relation index; - uint32 hash_mask; /* bitmask for hash codes */ + uint32 num_buckets; /* bitmask for hash codes */ }; @@ -52,15 +52,12 @@ _h_spoolinit(Relation heap, Relation index, uint32 num_buckets) hspool->index = index; /* - * Determine the bitmask for hash code values. Since there are currently - * num_buckets buckets in the index, the appropriate mask can be computed - * as follows. - * - * Note: at present, the passed-in num_buckets is always a power of 2, so - * we could just compute num_buckets - 1. We prefer not to assume that - * here, though. + * At this point max_buckets in hash index is num_buckets - 1. + * The "hash key mod num_buckets" will indicate which bucket does the + * hash key belongs to, and will be used to sort the index tuples based on + * their bucket. */ - hspool->hash_mask = (((uint32) 1) << _hash_log2(num_buckets)) - 1; + hspool->num_buckets = num_buckets; /* * We size the sort area as maintenance_work_mem rather than work_mem to @@ -69,7 +66,7 @@ _h_spoolinit(Relation heap, Relation index, uint32 num_buckets) */ hspool->sortstate = tuplesort_begin_index_hash(heap, index, - hspool->hash_mask, + hspool->num_buckets, maintenance_work_mem, false); @@ -122,7 +119,7 @@ _h_indexbuild(HSpool *hspool, Relation heapRel) #ifdef USE_ASSERT_CHECKING uint32 lasthashkey = hashkey; - hashkey = _hash_get_indextuple_hashkey(itup) & hspool->hash_mask; + hashkey = _hash_get_indextuple_hashkey(itup) % hspool->num_buckets; Assert(hashkey >= lasthashkey); #endif diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index e1e692d..675c6a8 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -126,6 +126,7 @@ #include #include "access/htup_details.h" +#include "access/hash.h" #include "access/nbtree.h" #include "catalog/index.h" #include "catalog/pg_am.h" @@ -473,7 +474,7 @@ struct Tuplesortstate bool enforceUnique; /* complain if we find duplicate tuples */ /* These are specific to the index_hash subcase: */ - uint32 hash_mask; /* mask for sortable part of hash code */ + uint32 num_buckets; /* to find the bucket of given hash key */ /* * These variables are specific to the Datum case; they are set by @@ -991,7 +992,7 @@ tuplesort_begin_index_btree(Relation heapRel, Tuplesortstate * tuplesort_begin_index_hash(Relation heapRel, Relation indexRel, - uint32 hash_mask, + uint32 num_buckets, int workMem, bool randomAccess) { Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess); @@ -1002,8 +1003,8 @@ tuplesort_begin_index_hash(Relation heapRel, #ifdef TRACE_SORT if (trace_sort) elog(LOG, - "begin index sort: hash_mask = 0x%x, workMem = %d, randomAccess = %c", - hash_mask, + "begin index sort: num_buckets = 0x%x, workMem = %d, randomAccess = %c", + num_buckets, workMem, randomAccess ? 't' : 'f'); #endif @@ -1017,7 +1018,7 @@ tuplesort_begin_index_hash(Relation heapRel, state->heapRel = heapRel; state->indexRel = indexRel; - state->hash_mask = hash_mask; + state->num_buckets = num_buckets; MemoryContextSwitchTo(oldcontext); @@ -4157,27 +4158,27 @@ static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { - uint32 hash1; - uint32 hash2; + Bucket bucket1; + Bucket bucket2; IndexTuple tuple1; IndexTuple tuple2; /* - * Fetch hash keys and mask off bits we don't want to sort by. We know - * that the first column of the index tuple is the hash key. + * Get the buckets of hash keys. We know that the first column of the index + * tuple is the hash key. */ Assert(!a->isnull1); - hash1 = DatumGetUInt32(a->datum1) & state->hash_mask; + bucket1 = DatumGetUInt32(a->datum1) % state->num_buckets; Assert(!b->isnull1); - hash2 = DatumGetUInt32(b->datum1) & state->hash_mask; + bucket2 = DatumGetUInt32(b->datum1) % state->num_buckets; - if (hash1 > hash2) + if (bucket1 > bucket2) return 1; - else if (hash1 < hash2) + else if (bucket1 < bucket2) return -1; /* - * If hash values are equal, we sort on ItemPointer. This does not affect + * If buckets are equal, we sort on ItemPointer. This does not affect * validity of the finished index, but it may be useful to have index * scans in physical order. */