diff options
Diffstat (limited to 'src/backend/utils/sort/lselect.c')
-rw-r--r-- | src/backend/utils/sort/lselect.c | 135 |
1 files changed, 46 insertions, 89 deletions
diff --git a/src/backend/utils/sort/lselect.c b/src/backend/utils/sort/lselect.c index 8c6c27ef46e..26a3ca38576 100644 --- a/src/backend/utils/sort/lselect.c +++ b/src/backend/utils/sort/lselect.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.3 1997/05/20 11:35:48 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.4 1997/08/06 03:41:47 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -26,37 +26,14 @@ #include "utils/psort.h" #include "utils/lselect.h" -extern Relation SortRdesc; /* later static */ - -/* - * PUTTUP - writes the next tuple - * ENDRUN - mark end of run - * GETLEN - reads the length of the next tuple - * ALLOCTUP - returns space for the new tuple - * SETTUPLEN - stores the length into the tuple - * GETTUP - reads the tuple - * - * Note: - * LEN field must be a short; FP is a stream - */ - #define PUTTUP(TUP, FP) fwrite((char *)TUP, (TUP)->t_len, 1, FP) -#define ENDRUN(FP) fwrite((char *)&shortzero, sizeof (shortzero), 1, FP) -#define GETLEN(LEN, FP) fread(&(LEN), sizeof (shortzero), 1, FP) -#define ALLOCTUP(LEN) ((HeapTuple)palloc((unsigned)LEN)) -#define GETTUP(TUP, LEN, FP)\ - fread((char *)(TUP) + sizeof (shortzero), 1, (LEN) - sizeof (shortzero), FP) -#define SETTUPLEN(TUP, LEN) (TUP)->t_len = LEN /* * USEMEM - record use of memory * FREEMEM - record freeing of memory - * FULLMEM - 1 iff a tuple will fit */ - -#define USEMEM(AMT) SortMemory -= (AMT) -#define FREEMEM(AMT) SortMemory += (AMT) -#define LACKMEM() (SortMemory <= BLCKSZ) /* not accurate */ +#define USEMEM(context,AMT) context->sortMem -= (AMT) +#define FREEMEM(context,AMT) context->sortMem += (AMT) /* * lmerge - merges two leftist trees into one @@ -67,12 +44,12 @@ extern Relation SortRdesc; /* later static */ * speed up code significantly. */ struct leftist * -lmerge(struct leftist *pt, struct leftist *qt) +lmerge(struct leftist *pt, struct leftist *qt, LeftistContext context) { register struct leftist *root, *majorLeftist, *minorLeftist; int dist; - if (tuplecmp(pt->lt_tuple, qt->lt_tuple)) { + if (tuplecmp(pt->lt_tuple, qt->lt_tuple, context)) { root = pt; majorLeftist = qt; } else { @@ -83,7 +60,7 @@ lmerge(struct leftist *pt, struct leftist *qt) root->lt_left = majorLeftist; else { if ((minorLeftist = root->lt_right) != NULL) - majorLeftist = lmerge(majorLeftist, minorLeftist); + majorLeftist = lmerge(majorLeftist, minorLeftist, context); if ((dist = root->lt_left->lt_dist) < majorLeftist->lt_dist) { root->lt_dist = 1 + dist; root->lt_right = root->lt_left; @@ -97,11 +74,11 @@ lmerge(struct leftist *pt, struct leftist *qt) } static struct leftist * -linsert(struct leftist *root, struct leftist *new1) +linsert(struct leftist *root, struct leftist *new1, LeftistContext context) { register struct leftist *left, *right; - if (! tuplecmp(root->lt_tuple, new1->lt_tuple)) { + if (! tuplecmp(root->lt_tuple, new1->lt_tuple, context)) { new1->lt_left = root; return(new1); } @@ -116,7 +93,7 @@ linsert(struct leftist *root, struct leftist *new1) } return(root); } - right = linsert(right, new1); + right = linsert(right, new1, context); if (right->lt_dist < left->lt_dist) { root->lt_dist = 1 + left->lt_dist; root->lt_left = right; @@ -142,7 +119,8 @@ linsert(struct leftist *root, struct leftist *new1) */ HeapTuple gettuple(struct leftist **treep, - short *devnum) /* device from which tuple came */ + short *devnum, /* device from which tuple came */ + LeftistContext context) { register struct leftist *tp; HeapTuple tup; @@ -153,9 +131,9 @@ gettuple(struct leftist **treep, if (tp->lt_dist == 1) /* lt_left == NULL */ *treep = tp->lt_left; else - *treep = lmerge(tp->lt_left, tp->lt_right); + *treep = lmerge(tp->lt_left, tp->lt_right, context); - FREEMEM(sizeof (struct leftist)); + FREEMEM(context,sizeof (struct leftist)); FREE(tp); return(tup); } @@ -169,14 +147,17 @@ gettuple(struct leftist **treep, * Note: * Currently never returns NULL BUG */ -int -puttuple(struct leftist **treep, HeapTuple newtuple, int devnum) +void +puttuple(struct leftist **treep, + HeapTuple newtuple, + short devnum, + LeftistContext context) { register struct leftist *new1; register struct leftist *tp; new1 = (struct leftist *) palloc((unsigned) sizeof (struct leftist)); - USEMEM(sizeof (struct leftist)); + USEMEM(context,sizeof (struct leftist)); new1->lt_dist = 1; new1->lt_devnum = devnum; new1->lt_tuple = newtuple; @@ -185,39 +166,12 @@ puttuple(struct leftist **treep, HeapTuple newtuple, int devnum) if ((tp = *treep) == NULL) *treep = new1; else - *treep = linsert(tp, new1); - return(1); + *treep = linsert(tp, new1, context); + return; } /* - * dumptuples - stores all the tuples in tree into file - */ -void -dumptuples(FILE *file) -{ - register struct leftist *tp; - register struct leftist *newp; - HeapTuple tup; - - tp = Tuples; - while (tp != NULL) { - tup = tp->lt_tuple; - if (tp->lt_dist == 1) /* lt_right == NULL */ - newp = tp->lt_left; - else - newp = lmerge(tp->lt_left, tp->lt_right); - FREEMEM(sizeof (struct leftist)); - FREE(tp); - PUTTUP(tup, file); - FREEMEM(tup->t_len); - FREE(tup); - tp = newp; - } - Tuples = NULL; -} - -/* * tuplecmp - Compares two tuples with respect CmpList * * Returns: @@ -225,7 +179,7 @@ dumptuples(FILE *file) * Assumtions: */ int -tuplecmp(HeapTuple ltup, HeapTuple rtup) +tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context) { register char *lattr, *rattr; int nkey = 0; @@ -238,24 +192,27 @@ tuplecmp(HeapTuple ltup, HeapTuple rtup) return(0); if (rtup == (HeapTuple)NULL) return(1); - while (nkey < Nkeys && !result) { + while (nkey < context->nKeys && !result) { lattr = heap_getattr(ltup, InvalidBuffer, - Key[nkey].sk_attno, - RelationGetTupleDescriptor(SortRdesc), - &isnull); + context->scanKeys[nkey].sk_attno, + context->tupDesc, &isnull); if (isnull) return(0); rattr = heap_getattr(rtup, InvalidBuffer, - Key[nkey].sk_attno, - RelationGetTupleDescriptor(SortRdesc), + context->scanKeys[nkey].sk_attno, + context->tupDesc, &isnull); if (isnull) return(1); - if (Key[nkey].sk_flags & SK_COMMUTE) { - if (!(result = (long) (*Key[nkey].sk_func) (rattr, lattr))) - result = -(long) (*Key[nkey].sk_func) (lattr, rattr); - } else if (!(result = (long) (*Key[nkey].sk_func) (lattr, rattr))) - result = -(long) (*Key[nkey].sk_func) (rattr, lattr); + if (context->scanKeys[nkey].sk_flags & SK_COMMUTE) { + if (!(result = + (long) (*context->scanKeys[nkey].sk_func) (rattr, lattr))) + result = + -(long) (*context->scanKeys[nkey].sk_func) (lattr, rattr); + } else if (!(result = + (long) (*context->scanKeys[nkey].sk_func) (lattr, rattr))) + result = + -(long) (*context->scanKeys[nkey].sk_func) (rattr, lattr); nkey++; } return (result == 1); @@ -263,7 +220,7 @@ tuplecmp(HeapTuple ltup, HeapTuple rtup) #ifdef EBUG void -checktree(struct leftist *tree) +checktree(struct leftist *tree, LeftistContext context) { int lnodes; int rnodes; @@ -272,8 +229,8 @@ checktree(struct leftist *tree) puts("Null tree."); return; } - lnodes = checktreer(tree->lt_left, 1); - rnodes = checktreer(tree->lt_right, 1); + lnodes = checktreer(tree->lt_left, 1, context); + rnodes = checktreer(tree->lt_right, 1, context); if (lnodes < 0) { lnodes = -lnodes; puts("0:\tBad left side."); @@ -297,24 +254,24 @@ checktree(struct leftist *tree) } else if (tree->lt_dist != 1+ tree->lt_right->lt_dist) puts("0:\tDistance incorrect."); if (lnodes > 0) - if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple)) + if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple, context)) printf("%d:\tLeft child < parent.\n"); if (rnodes > 0) - if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple)) + if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple, context)) printf("%d:\tRight child < parent.\n"); printf("Tree has %d nodes\n", 1 + lnodes + rnodes); } int -checktreer(struct leftist *tree, int level) +checktreer(struct leftist *tree, int level, LeftistContext context) { int lnodes, rnodes; int error = 0; if (tree == NULL) return(0); - lnodes = checktreer(tree->lt_left, level + 1); - rnodes = checktreer(tree->lt_right, level + 1); + lnodes = checktreer(tree->lt_left, level + 1, context); + rnodes = checktreer(tree->lt_right, level + 1, context); if (lnodes < 0) { error = 1; lnodes = -lnodes; @@ -349,12 +306,12 @@ checktreer(struct leftist *tree, int level) printf("%d:\tDistance incorrect.\n", level); } if (lnodes > 0) - if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple)) { + if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple, context)) { error = 1; printf("%d:\tLeft child < parent.\n"); } if (rnodes > 0) - if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple)) { + if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple, context)) { error = 1; printf("%d:\tRight child < parent.\n"); } |