mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Adjust tuplesort API to have bitwise option flags
This replaces the bool flag for randomAccess. An upcoming patch requires adding another option, so instead of breaking the API for that, then breaking it again one day if we add more options, let's just break it once. Any boolean options we add in the future will just make use of an unused bit in the flags. Any extensions making use of tuplesorts will need to update their code to pass TUPLESORT_RANDOMACCESS instead of true for randomAccess. TUPLESORT_NONE can be used for a set of empty options. Author: David Rowley Reviewed-by: Justin Pryzby Discussion: https://postgr.es/m/CAApHDvoH4ASzsAOyHcxkuY01Qf%2B%2B8JJ0paw%2B03dk%2BW25tQEcNQ%40mail.gmail.com
This commit is contained in:
@@ -246,7 +246,7 @@ struct Tuplesortstate
|
||||
{
|
||||
TupSortStatus status; /* enumerated value as shown above */
|
||||
int nKeys; /* number of columns in sort key */
|
||||
bool randomAccess; /* did caller request random access? */
|
||||
int sortopt; /* Bitmask of flags used to setup sort */
|
||||
bool bounded; /* did caller specify a maximum number of
|
||||
* tuples to return? */
|
||||
bool boundUsed; /* true if we made use of a bounded heap */
|
||||
@@ -564,12 +564,12 @@ struct Sharedsort
|
||||
* may or may not match the in-memory representation of the tuple ---
|
||||
* any conversion needed is the job of the writetup and readtup routines.
|
||||
*
|
||||
* If state->randomAccess is true, then the stored representation of the
|
||||
* tuple must be followed by another "unsigned int" that is a copy of the
|
||||
* length --- so the total tape space used is actually sizeof(unsigned int)
|
||||
* more than the stored length value. This allows read-backwards. When
|
||||
* randomAccess is not true, the write/read routines may omit the extra
|
||||
* length word.
|
||||
* If state->sortopt contains TUPLESORT_RANDOMACCESS, then the stored
|
||||
* representation of the tuple must be followed by another "unsigned int" that
|
||||
* is a copy of the length --- so the total tape space used is actually
|
||||
* sizeof(unsigned int) more than the stored length value. This allows
|
||||
* read-backwards. When the random access flag was not specified, the
|
||||
* write/read routines may omit the extra length word.
|
||||
*
|
||||
* writetup is expected to write both length words as well as the tuple
|
||||
* data. When readtup is called, the tape is positioned just after the
|
||||
@@ -614,7 +614,7 @@ struct Sharedsort
|
||||
|
||||
static Tuplesortstate *tuplesort_begin_common(int workMem,
|
||||
SortCoordinate coordinate,
|
||||
bool randomAccess);
|
||||
int sortopt);
|
||||
static void tuplesort_begin_batch(Tuplesortstate *state);
|
||||
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple);
|
||||
static bool consider_abort_common(Tuplesortstate *state);
|
||||
@@ -806,21 +806,20 @@ qsort_tuple_int32_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
|
||||
* Each variant of tuplesort_begin has a workMem parameter specifying the
|
||||
* maximum number of kilobytes of RAM to use before spilling data to disk.
|
||||
* (The normal value of this parameter is work_mem, but some callers use
|
||||
* other values.) Each variant also has a randomAccess parameter specifying
|
||||
* whether the caller needs non-sequential access to the sort result.
|
||||
* other values.) Each variant also has a sortopt which is a bitmask of
|
||||
* sort options. See TUPLESORT_* definitions in tuplesort.h
|
||||
*/
|
||||
|
||||
static Tuplesortstate *
|
||||
tuplesort_begin_common(int workMem, SortCoordinate coordinate,
|
||||
bool randomAccess)
|
||||
tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
|
||||
{
|
||||
Tuplesortstate *state;
|
||||
MemoryContext maincontext;
|
||||
MemoryContext sortcontext;
|
||||
MemoryContext oldcontext;
|
||||
|
||||
/* See leader_takeover_tapes() remarks on randomAccess support */
|
||||
if (coordinate && randomAccess)
|
||||
/* See leader_takeover_tapes() remarks on random access support */
|
||||
if (coordinate && (sortopt & TUPLESORT_RANDOMACCESS))
|
||||
elog(ERROR, "random access disallowed under parallel sort");
|
||||
|
||||
/*
|
||||
@@ -857,7 +856,7 @@ tuplesort_begin_common(int workMem, SortCoordinate coordinate,
|
||||
pg_rusage_init(&state->ru_start);
|
||||
#endif
|
||||
|
||||
state->randomAccess = randomAccess;
|
||||
state->sortopt = sortopt;
|
||||
state->tuples = true;
|
||||
|
||||
/*
|
||||
@@ -991,10 +990,10 @@ tuplesort_begin_heap(TupleDesc tupDesc,
|
||||
int nkeys, AttrNumber *attNums,
|
||||
Oid *sortOperators, Oid *sortCollations,
|
||||
bool *nullsFirstFlags,
|
||||
int workMem, SortCoordinate coordinate, bool randomAccess)
|
||||
int workMem, SortCoordinate coordinate, int sortopt)
|
||||
{
|
||||
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
|
||||
randomAccess);
|
||||
sortopt);
|
||||
MemoryContext oldcontext;
|
||||
int i;
|
||||
|
||||
@@ -1006,7 +1005,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
|
||||
if (trace_sort)
|
||||
elog(LOG,
|
||||
"begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
|
||||
nkeys, workMem, randomAccess ? 't' : 'f');
|
||||
nkeys, workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
|
||||
#endif
|
||||
|
||||
state->nKeys = nkeys;
|
||||
@@ -1015,7 +1014,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
|
||||
false, /* no unique check */
|
||||
nkeys,
|
||||
workMem,
|
||||
randomAccess,
|
||||
sortopt & TUPLESORT_RANDOMACCESS,
|
||||
PARALLEL_SORT(state));
|
||||
|
||||
state->comparetup = comparetup_heap;
|
||||
@@ -1065,10 +1064,10 @@ Tuplesortstate *
|
||||
tuplesort_begin_cluster(TupleDesc tupDesc,
|
||||
Relation indexRel,
|
||||
int workMem,
|
||||
SortCoordinate coordinate, bool randomAccess)
|
||||
SortCoordinate coordinate, int sortopt)
|
||||
{
|
||||
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
|
||||
randomAccess);
|
||||
sortopt);
|
||||
BTScanInsert indexScanKey;
|
||||
MemoryContext oldcontext;
|
||||
int i;
|
||||
@@ -1082,7 +1081,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
|
||||
elog(LOG,
|
||||
"begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
|
||||
RelationGetNumberOfAttributes(indexRel),
|
||||
workMem, randomAccess ? 't' : 'f');
|
||||
workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
|
||||
#endif
|
||||
|
||||
state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
|
||||
@@ -1091,7 +1090,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
|
||||
false, /* no unique check */
|
||||
state->nKeys,
|
||||
workMem,
|
||||
randomAccess,
|
||||
sortopt & TUPLESORT_RANDOMACCESS,
|
||||
PARALLEL_SORT(state));
|
||||
|
||||
state->comparetup = comparetup_cluster;
|
||||
@@ -1172,10 +1171,10 @@ tuplesort_begin_index_btree(Relation heapRel,
|
||||
bool uniqueNullsNotDistinct,
|
||||
int workMem,
|
||||
SortCoordinate coordinate,
|
||||
bool randomAccess)
|
||||
int sortopt)
|
||||
{
|
||||
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
|
||||
randomAccess);
|
||||
sortopt);
|
||||
BTScanInsert indexScanKey;
|
||||
MemoryContext oldcontext;
|
||||
int i;
|
||||
@@ -1187,7 +1186,7 @@ tuplesort_begin_index_btree(Relation heapRel,
|
||||
elog(LOG,
|
||||
"begin index sort: unique = %c, workMem = %d, randomAccess = %c",
|
||||
enforceUnique ? 't' : 'f',
|
||||
workMem, randomAccess ? 't' : 'f');
|
||||
workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
|
||||
#endif
|
||||
|
||||
state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
|
||||
@@ -1196,7 +1195,7 @@ tuplesort_begin_index_btree(Relation heapRel,
|
||||
enforceUnique,
|
||||
state->nKeys,
|
||||
workMem,
|
||||
randomAccess,
|
||||
sortopt & TUPLESORT_RANDOMACCESS,
|
||||
PARALLEL_SORT(state));
|
||||
|
||||
state->comparetup = comparetup_index_btree;
|
||||
@@ -1254,10 +1253,10 @@ tuplesort_begin_index_hash(Relation heapRel,
|
||||
uint32 max_buckets,
|
||||
int workMem,
|
||||
SortCoordinate coordinate,
|
||||
bool randomAccess)
|
||||
int sortopt)
|
||||
{
|
||||
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
|
||||
randomAccess);
|
||||
sortopt);
|
||||
MemoryContext oldcontext;
|
||||
|
||||
oldcontext = MemoryContextSwitchTo(state->maincontext);
|
||||
@@ -1270,7 +1269,8 @@ tuplesort_begin_index_hash(Relation heapRel,
|
||||
high_mask,
|
||||
low_mask,
|
||||
max_buckets,
|
||||
workMem, randomAccess ? 't' : 'f');
|
||||
workMem,
|
||||
sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
|
||||
#endif
|
||||
|
||||
state->nKeys = 1; /* Only one sort column, the hash code */
|
||||
@@ -1298,10 +1298,10 @@ tuplesort_begin_index_gist(Relation heapRel,
|
||||
Relation indexRel,
|
||||
int workMem,
|
||||
SortCoordinate coordinate,
|
||||
bool randomAccess)
|
||||
int sortopt)
|
||||
{
|
||||
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
|
||||
randomAccess);
|
||||
sortopt);
|
||||
MemoryContext oldcontext;
|
||||
int i;
|
||||
|
||||
@@ -1311,7 +1311,7 @@ tuplesort_begin_index_gist(Relation heapRel,
|
||||
if (trace_sort)
|
||||
elog(LOG,
|
||||
"begin index sort: workMem = %d, randomAccess = %c",
|
||||
workMem, randomAccess ? 't' : 'f');
|
||||
workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
|
||||
#endif
|
||||
|
||||
state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
|
||||
@@ -1354,10 +1354,10 @@ tuplesort_begin_index_gist(Relation heapRel,
|
||||
Tuplesortstate *
|
||||
tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
|
||||
bool nullsFirstFlag, int workMem,
|
||||
SortCoordinate coordinate, bool randomAccess)
|
||||
SortCoordinate coordinate, int sortopt)
|
||||
{
|
||||
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
|
||||
randomAccess);
|
||||
sortopt);
|
||||
MemoryContext oldcontext;
|
||||
int16 typlen;
|
||||
bool typbyval;
|
||||
@@ -1368,7 +1368,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
|
||||
if (trace_sort)
|
||||
elog(LOG,
|
||||
"begin datum sort: workMem = %d, randomAccess = %c",
|
||||
workMem, randomAccess ? 't' : 'f');
|
||||
workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
|
||||
#endif
|
||||
|
||||
state->nKeys = 1; /* always a one-column sort */
|
||||
@@ -1377,7 +1377,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
|
||||
false, /* no unique check */
|
||||
1,
|
||||
workMem,
|
||||
randomAccess,
|
||||
sortopt & TUPLESORT_RANDOMACCESS,
|
||||
PARALLEL_SORT(state));
|
||||
|
||||
state->comparetup = comparetup_datum;
|
||||
@@ -2272,7 +2272,7 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward,
|
||||
switch (state->status)
|
||||
{
|
||||
case TSS_SORTEDINMEM:
|
||||
Assert(forward || state->randomAccess);
|
||||
Assert(forward || state->sortopt & TUPLESORT_RANDOMACCESS);
|
||||
Assert(!state->slabAllocatorUsed);
|
||||
if (forward)
|
||||
{
|
||||
@@ -2316,7 +2316,7 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward,
|
||||
break;
|
||||
|
||||
case TSS_SORTEDONTAPE:
|
||||
Assert(forward || state->randomAccess);
|
||||
Assert(forward || state->sortopt & TUPLESORT_RANDOMACCESS);
|
||||
Assert(state->slabAllocatorUsed);
|
||||
|
||||
/*
|
||||
@@ -3091,7 +3091,8 @@ mergeruns(Tuplesortstate *state)
|
||||
* sorted tape, we can stop at this point and do the final merge
|
||||
* on-the-fly.
|
||||
*/
|
||||
if (!state->randomAccess && state->nInputRuns <= state->nInputTapes
|
||||
if ((state->sortopt & TUPLESORT_RANDOMACCESS) == 0
|
||||
&& state->nInputRuns <= state->nInputTapes
|
||||
&& !WORKER(state))
|
||||
{
|
||||
/* Tell logtape.c we won't be writing anymore */
|
||||
@@ -3337,7 +3338,7 @@ tuplesort_rescan(Tuplesortstate *state)
|
||||
{
|
||||
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
|
||||
|
||||
Assert(state->randomAccess);
|
||||
Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
|
||||
|
||||
switch (state->status)
|
||||
{
|
||||
@@ -3370,7 +3371,7 @@ tuplesort_markpos(Tuplesortstate *state)
|
||||
{
|
||||
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
|
||||
|
||||
Assert(state->randomAccess);
|
||||
Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
|
||||
|
||||
switch (state->status)
|
||||
{
|
||||
@@ -3401,7 +3402,7 @@ tuplesort_restorepos(Tuplesortstate *state)
|
||||
{
|
||||
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
|
||||
|
||||
Assert(state->randomAccess);
|
||||
Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
|
||||
|
||||
switch (state->status)
|
||||
{
|
||||
@@ -3998,7 +3999,8 @@ writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
|
||||
|
||||
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
|
||||
LogicalTapeWrite(tape, (void *) tupbody, tupbodylen);
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
|
||||
|
||||
if (!state->slabAllocatorUsed)
|
||||
@@ -4021,7 +4023,8 @@ readtup_heap(Tuplesortstate *state, SortTuple *stup,
|
||||
/* read in the tuple proper */
|
||||
tuple->t_len = tuplen;
|
||||
LogicalTapeReadExact(tape, tupbody, tupbodylen);
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
|
||||
stup->tuple = (void *) tuple;
|
||||
/* set up first-column key value */
|
||||
@@ -4233,7 +4236,8 @@ writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
|
||||
LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
|
||||
LogicalTapeWrite(tape, &tuple->t_self, sizeof(ItemPointerData));
|
||||
LogicalTapeWrite(tape, tuple->t_data, tuple->t_len);
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
|
||||
|
||||
if (!state->slabAllocatorUsed)
|
||||
@@ -4259,7 +4263,8 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup,
|
||||
tuple->t_tableOid = InvalidOid;
|
||||
/* Read in the tuple body */
|
||||
LogicalTapeReadExact(tape, tuple->t_data, tuple->t_len);
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
|
||||
stup->tuple = (void *) tuple;
|
||||
/* set up first-column key value, if it's a simple column */
|
||||
@@ -4483,7 +4488,8 @@ writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
|
||||
tuplen = IndexTupleSize(tuple) + sizeof(tuplen);
|
||||
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
|
||||
LogicalTapeWrite(tape, (void *) tuple, IndexTupleSize(tuple));
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
|
||||
|
||||
if (!state->slabAllocatorUsed)
|
||||
@@ -4501,7 +4507,8 @@ readtup_index(Tuplesortstate *state, SortTuple *stup,
|
||||
IndexTuple tuple = (IndexTuple) readtup_alloc(state, tuplen);
|
||||
|
||||
LogicalTapeReadExact(tape, tuple, tuplen);
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
|
||||
stup->tuple = (void *) tuple;
|
||||
/* set up first-column key value */
|
||||
@@ -4571,7 +4578,8 @@ writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
|
||||
|
||||
LogicalTapeWrite(tape, (void *) &writtenlen, sizeof(writtenlen));
|
||||
LogicalTapeWrite(tape, waddr, tuplen);
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeWrite(tape, (void *) &writtenlen, sizeof(writtenlen));
|
||||
|
||||
if (!state->slabAllocatorUsed && stup->tuple)
|
||||
@@ -4611,7 +4619,8 @@ readtup_datum(Tuplesortstate *state, SortTuple *stup,
|
||||
stup->tuple = raddr;
|
||||
}
|
||||
|
||||
if (state->randomAccess) /* need trailing length word? */
|
||||
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
|
||||
* word? */
|
||||
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user