Commit b0ccd784 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

Don't limit number of tuples in leftist trees!

Use qsort to sort array of tuples for nextrun when current
run is done and put into leftist tree from sorted array!
It's much faster and creates non-bushy tree - this is ve-e-ery good
for perfomance!
parent 8f1e1b45
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.23 1997/09/18 05:37:31 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.24 1997/09/18 14:41:56 vadim Exp $
* *
* NOTES * NOTES
* Sorts the first relation into the second relation. * Sorts the first relation into the second relation.
...@@ -147,8 +147,6 @@ psort_begin(Sort * node, int nkeys, ScanKey key) ...@@ -147,8 +147,6 @@ psort_begin(Sort * node, int nkeys, ScanKey key)
PS(node)->treeContext.sortMem = SortMem * 1024; PS(node)->treeContext.sortMem = SortMem * 1024;
PS(node)->Tuples = NULL; PS(node)->Tuples = NULL;
PS(node)->lasttuple = NULL;
PS(node)->lt_tupcount = 0;
PS(node)->tupcount = 0; PS(node)->tupcount = 0;
PS(node)->using_tape_files = false; PS(node)->using_tape_files = false;
...@@ -434,45 +432,14 @@ createfirstrun(Sort *node) ...@@ -434,45 +432,14 @@ createfirstrun(Sort *node)
if ( LACKMEM (node) ) /* in-memory sort is impossible */ if ( LACKMEM (node) ) /* in-memory sort is impossible */
{ {
register int t; register int t;
register int f;
FILE *file;
Assert (!foundeor); Assert (!foundeor);
inittapes(node); inittapes(node);
file = PS(node)->Tape->tp_file; /* put tuples into leftist tree for createrun */
for (t = t_last - 1 ; t >= 0; t--)
/* put extra tuples into tape file */
if ( t_last > SortTuplesInTree )
{
register HeapTuple lasttuple;
t = t_last - SortTuplesInTree;
for (f = 0, lasttuple = NULL; f < t; f++)
{
if ( lasttuple )
{
FREEMEM(node, lasttuple->t_len);
FREE(lasttuple);
TRACEMEM(createfirstrun);
}
lasttuple = memtuples[f];
PUTTUP(node, lasttuple, file);
TRACEOUT(createfirstrun, lasttuple);
}
PS(node)->lasttuple = lasttuple;
}
else
{
PS(node)->lasttuple = NULL;
f = 0;
}
/* put rest of tuples into leftist tree for createrun */
for (t = t_last - 1 ; t >= f; t--)
puttuple(&PS(node)->Tuples, memtuples[t], 0, &PS(node)->treeContext); puttuple(&PS(node)->Tuples, memtuples[t], 0, &PS(node)->treeContext);
PS(node)->lt_tupcount = t_last - f;
pfree (memtuples); pfree (memtuples);
foundeor = !createrun (node, file); foundeor = !createrun (node, PS(node)->Tape->tp_file);
} }
else else
{ {
...@@ -497,50 +464,41 @@ createfirstrun(Sort *node) ...@@ -497,50 +464,41 @@ createfirstrun(Sort *node)
static bool static bool
createrun(Sort * node, FILE * file) createrun(Sort * node, FILE * file)
{ {
register HeapTuple lasttuple; register HeapTuple lasttuple;
register HeapTuple tup; register HeapTuple tup;
struct leftist *nextrun; TupleTableSlot *cr_slot;
bool foundeor; HeapTuple *memtuples;
short junk; int t_last = -1;
int curr_tupcount = (PS(node)->Tuples != NULL) ? PS(node)->lt_tupcount : 0; int t_free = 1000;
int next_tupcount = 0; bool foundeor = false;
short junk;
int cr_tuples = 0; /* Count tuples grabbed from plannode */
TupleTableSlot *cr_slot;
Assert(node != (Sort *) NULL); Assert(node != (Sort *) NULL);
Assert(PS(node) != (Psortstate *) NULL); Assert(PS(node) != (Psortstate *) NULL);
Assert (PS(node)->using_tape_files);
lasttuple = PS(node)->lasttuple; /* !NULL if called from createfirstrun */ lasttuple = NULL;
nextrun = NULL; memtuples = palloc(t_free * sizeof(HeapTuple));
foundeor = false;
for (;;) for (;;)
{ {
if ((LACKMEM(node) && PS(node)->Tuples != NULL) || curr_tupcount > SortTuplesInTree) while (LACKMEM(node) && PS(node)->Tuples != NULL)
{ {
do if (lasttuple != NULL)
{ {
if (lasttuple != NULL) FREEMEM(node, lasttuple->t_len);
{ FREE(lasttuple);
FREEMEM(node, lasttuple->t_len); TRACEMEM(createrun);
FREE(lasttuple); }
TRACEMEM(createrun); lasttuple = gettuple(&PS(node)->Tuples, &junk,
}
lasttuple = tup = gettuple(&PS(node)->Tuples, &junk,
&PS(node)->treeContext); &PS(node)->treeContext);
Assert (PS(node)->using_tape_files); PUTTUP(node, lasttuple, file);
PUTTUP(node, tup, file); TRACEOUT(createrun, lasttuple);
TRACEOUT(createrun, tup);
curr_tupcount--;
} while (LACKMEM(node) && PS(node)->Tuples != NULL);
} }
if (LACKMEM(node)) if (LACKMEM(node))
break; break;
if ( next_tupcount >= SortTuplesInTree )
break;
/* /*
* About to call ExecProcNode, it can mess up the state if it * About to call ExecProcNode, it can mess up the state if it
* eventually calls another Sort node. So must stow it away here * eventually calls another Sort node. So must stow it away here
...@@ -560,7 +518,6 @@ createrun(Sort * node, FILE * file) ...@@ -560,7 +518,6 @@ createrun(Sort * node, FILE * file)
tup = tuplecopy(cr_slot->val); tup = tuplecopy(cr_slot->val);
ExecClearTuple(cr_slot); ExecClearTuple(cr_slot);
PS(node)->tupcount++; PS(node)->tupcount++;
cr_tuples++;
} }
IncrProcessed(); IncrProcessed();
...@@ -569,14 +526,18 @@ createrun(Sort * node, FILE * file) ...@@ -569,14 +526,18 @@ createrun(Sort * node, FILE * file)
if (lasttuple != NULL && tuplecmp(tup, lasttuple, if (lasttuple != NULL && tuplecmp(tup, lasttuple,
&PS(node)->treeContext)) &PS(node)->treeContext))
{ {
puttuple(&nextrun, tup, 0, &PS(node)->treeContext); if ( t_free <= 0 )
next_tupcount++; {
t_free = 1000;
memtuples = repalloc (memtuples,
(t_last + t_free + 1) * sizeof (HeapTuple));
}
t_last++;
t_free--;
memtuples[t_last] = tup;
} }
else else
{
puttuple(&PS(node)->Tuples, tup, 0, &PS(node)->treeContext); puttuple(&PS(node)->Tuples, tup, 0, &PS(node)->treeContext);
curr_tupcount++;
}
} }
if (lasttuple != NULL) if (lasttuple != NULL)
{ {
...@@ -585,13 +546,26 @@ createrun(Sort * node, FILE * file) ...@@ -585,13 +546,26 @@ createrun(Sort * node, FILE * file)
TRACEMEM(createrun); TRACEMEM(createrun);
} }
dumptuples(file, node); dumptuples(file, node);
ENDRUN(file); ENDRUN(file); /* delimit the end of the run */
/* delimit the end of the run */
PS(node)->Tuples = nextrun; t_last++;
PS(node)->lt_tupcount = next_tupcount; /* put tuples for the next run into leftist tree */
PS(node)->lasttuple = NULL; if ( t_last >= 1 )
{
register int t;
PsortTupDesc = PS(node)->treeContext.tupDesc;
PsortKeys = PS(node)->treeContext.scanKeys;
PsortNkeys = PS(node)->treeContext.nKeys;
qsort (memtuples, t_last, sizeof (HeapTuple),
(int (*)(const void *,const void *))_psort_cmp);
for (t = t_last - 1 ; t >= 0; t--)
puttuple(&PS(node)->Tuples, memtuples[t], 0, &PS(node)->treeContext);
}
pfree (memtuples);
return ((bool) ! foundeor); /* XXX - works iff bool is {0,1} */ return (!foundeor);
} }
/* /*
...@@ -774,8 +748,7 @@ dumptuples(FILE * file, Sort * node) ...@@ -774,8 +748,7 @@ dumptuples(FILE * file, Sort * node)
newp = tp->lt_left; newp = tp->lt_left;
else else
newp = lmerge(tp->lt_left, tp->lt_right, context); newp = lmerge(tp->lt_left, tp->lt_right, context);
FREEMEM(node, sizeof(struct leftist)); pfree(tp);
FREE(tp);
PUTTUP(node, tup, file); PUTTUP(node, tup, file);
FREEMEM(node, tup->t_len); FREEMEM(node, tup->t_len);
FREE(tup); FREE(tup);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment