sortbuild_hash_A_2.patch
application/octet-stream
Filename: sortbuild_hash_A_2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/hash/hashsort.c | 20 | 7 |
| src/backend/utils/sort/tuplesort.c | 25 | 12 |
| src/include/utils/tuplesort.h | 3 | 1 |
commit e73b27c9412ab916a7fb6e111238c9ecd1a72def
Author: mithun <mithun@localhost.localdomain>
Date: Sat Apr 1 12:55:13 2017 +0530
commit 2
diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c
index 0e0f393..41d615d 100644
--- a/src/backend/access/hash/hashsort.c
+++ b/src/backend/access/hash/hashsort.c
@@ -37,7 +37,15 @@ struct HSpool
{
Tuplesortstate *sortstate; /* state data for tuplesort.c */
Relation index;
- uint32 hash_mask; /* bitmask for hash codes */
+
+ /*
+ * We sort the hash keys based on the buckets they belong to. Below masks
+ * are used in _hash_hashkey2bucket to determine the bucket of given hash
+ * key.
+ */
+ uint32 high_mask;
+ uint32 low_mask;
+ uint32 max_buckets;
};
@@ -56,11 +64,12 @@ _h_spoolinit(Relation heap, Relation index, uint32 num_buckets)
* 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.
+ * NOTE : This hash mask calculation should be in sync with similar
+ * calculation in _hash_init_metabuffer.
*/
- hspool->hash_mask = (((uint32) 1) << _hash_log2(num_buckets)) - 1;
+ hspool->high_mask = (((uint32) 1) << _hash_log2(num_buckets + 1)) - 1;
+ hspool->low_mask = (hspool->high_mask >> 1);
+ hspool->max_buckets = num_buckets - 1;
/*
* We size the sort area as maintenance_work_mem rather than work_mem to
@@ -69,7 +78,9 @@ _h_spoolinit(Relation heap, Relation index, uint32 num_buckets)
*/
hspool->sortstate = tuplesort_begin_index_hash(heap,
index,
- hspool->hash_mask,
+ hspool->high_mask,
+ hspool->low_mask,
+ hspool->max_buckets,
maintenance_work_mem,
false);
@@ -122,7 +133,9 @@ _h_indexbuild(HSpool *hspool, Relation heapRel)
#ifdef USE_ASSERT_CHECKING
uint32 lasthashkey = hashkey;
- hashkey = _hash_get_indextuple_hashkey(itup) & hspool->hash_mask;
+ hashkey = _hash_hashkey2bucket(_hash_get_indextuple_hashkey(itup),
+ hspool->max_buckets, hspool->high_mask,
+ hspool->low_mask);
Assert(hashkey >= lasthashkey);
#endif
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index e1e692d..65cda52 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -127,6 +127,7 @@
#include "access/htup_details.h"
#include "access/nbtree.h"
+#include "access/hash.h"
#include "catalog/index.h"
#include "catalog/pg_am.h"
#include "commands/tablespace.h"
@@ -473,7 +474,9 @@ 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 high_mask; /* masks for sortable part of hash code */
+ uint32 low_mask;
+ uint32 max_buckets;
/*
* These variables are specific to the Datum case; they are set by
@@ -991,7 +994,9 @@ tuplesort_begin_index_btree(Relation heapRel,
Tuplesortstate *
tuplesort_begin_index_hash(Relation heapRel,
Relation indexRel,
- uint32 hash_mask,
+ uint32 high_mask,
+ uint32 low_mask,
+ uint32 max_buckets,
int workMem, bool randomAccess)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
@@ -1002,8 +1007,11 @@ 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: high_mask = 0x%x, low_mask = 0x%x, "
+ "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
+ high_mask,
+ low_mask,
+ max_buckets,
workMem, randomAccess ? 't' : 'f');
#endif
@@ -1017,7 +1025,9 @@ tuplesort_begin_index_hash(Relation heapRel,
state->heapRel = heapRel;
state->indexRel = indexRel;
- state->hash_mask = hash_mask;
+ state->high_mask = high_mask;
+ state->low_mask = low_mask;
+ state->max_buckets = max_buckets;
MemoryContextSwitchTo(oldcontext);
@@ -4157,8 +4167,8 @@ 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;
@@ -4167,13 +4177,16 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b,
* that the first column of the index tuple is the hash key.
*/
Assert(!a->isnull1);
- hash1 = DatumGetUInt32(a->datum1) & state->hash_mask;
+ bucket1 = _hash_hashkey2bucket(DatumGetUInt32(a->datum1),
+ state->max_buckets, state->high_mask,
+ state->low_mask);
Assert(!b->isnull1);
- hash2 = DatumGetUInt32(b->datum1) & state->hash_mask;
-
- if (hash1 > hash2)
+ bucket2 = _hash_hashkey2bucket(DatumGetUInt32(b->datum1),
+ state->max_buckets, state->high_mask,
+ state->low_mask);
+ if (bucket1 > bucket2)
return 1;
- else if (hash1 < hash2)
+ else if (bucket1 < bucket2)
return -1;
/*
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index 5b3f475..9719db4 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -72,7 +72,9 @@ extern Tuplesortstate *tuplesort_begin_index_btree(Relation heapRel,
int workMem, bool randomAccess);
extern Tuplesortstate *tuplesort_begin_index_hash(Relation heapRel,
Relation indexRel,
- uint32 hash_mask,
+ uint32 high_mask,
+ uint32 low_mask,
+ uint32 max_buckets,
int workMem, bool randomAccess);
extern Tuplesortstate *tuplesort_begin_datum(Oid datumType,
Oid sortOperator, Oid sortCollation,