~ubuntu-branches/ubuntu/trusty/postgresql-8.4/trusty

« back to all changes in this revision

Viewing changes to src/backend/utils/sort/tuplestore.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 * When the caller requests backward-scan capability, we write the temp file
30
30
 * in a format that allows either forward or backward scan.  Otherwise, only
31
31
 * forward scan is allowed.  A request for backward scan must be made before
32
 
 * putting any tuples into the tuplestore.  Rewind is normally allowed but
 
32
 * putting any tuples into the tuplestore.      Rewind is normally allowed but
33
33
 * can be turned off via tuplestore_set_eflags; turning off rewind for all
34
34
 * read pointers enables truncation of the tuplestore at the oldest read point
35
35
 * for minimal memory usage.  (The caller must explicitly call tuplestore_trim
47
47
 * Portions Copyright (c) 1994, Regents of the University of California
48
48
 *
49
49
 * IDENTIFICATION
50
 
 *        $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.47 2009/03/27 18:30:21 tgl Exp $
 
50
 *        $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.48 2009/06/11 14:49:06 momjian Exp $
51
51
 *
52
52
 *-------------------------------------------------------------------------
53
53
 */
81
81
 *
82
82
 * Special case: if eof_reached is true, then the pointer's read position is
83
83
 * implicitly equal to the write position, and current/file/offset aren't
84
 
 * maintained.  This way we need not update all the read pointers each time
 
84
 * maintained.  This way we need not update all the read pointers each time
85
85
 * we write.
86
86
 */
87
87
typedef struct
161
161
        int                     readptrsize;    /* allocated length of readptrs array */
162
162
 
163
163
        int                     writepos_file;  /* file# (valid if READFILE state) */
164
 
        off_t           writepos_offset; /* offset (valid if READFILE state) */
 
164
        off_t           writepos_offset;        /* offset (valid if READFILE state) */
165
165
};
166
166
 
167
167
#define COPYTUP(state,tup)      ((*(state)->copytup) (state, tup))
363
363
        /* Make room for another read pointer if needed */
364
364
        if (state->readptrcount >= state->readptrsize)
365
365
        {
366
 
                int             newcnt = state->readptrsize * 2;
 
366
                int                     newcnt = state->readptrsize * 2;
367
367
 
368
368
                state->readptrs = (TSReadPointer *)
369
369
                        repalloc(state->readptrs, newcnt * sizeof(TSReadPointer));
460
460
                        /* no work */
461
461
                        break;
462
462
                case TSS_READFILE:
 
463
 
463
464
                        /*
464
 
                         * First, save the current read position in the pointer about
465
 
                         * to become inactive.
 
465
                         * First, save the current read position in the pointer about to
 
466
                         * become inactive.
466
467
                         */
467
468
                        if (!oldptr->eof_reached)
468
469
                                BufFileTell(state->myfile,
635
636
                         */
636
637
                        PrepareTempTablespaces();
637
638
                        state->myfile = BufFileCreateTemp(state->interXact);
 
639
 
638
640
                        /*
639
 
                         * Freeze the decision about whether trailing length words
640
 
                         * will be used.  We can't change this choice once data is on
641
 
                         * tape, even though callers might drop the requirement.
 
641
                         * Freeze the decision about whether trailing length words will be
 
642
                         * used.  We can't change this choice once data is on tape, even
 
643
                         * though callers might drop the requirement.
642
644
                         */
643
645
                        state->backward = (state->eflags & EXEC_FLAG_BACKWARD) != 0;
644
646
                        state->status = TSS_WRITEFILE;
647
649
                case TSS_WRITEFILE:
648
650
 
649
651
                        /*
650
 
                         * Update read pointers as needed; see API spec above.
651
 
                         * Note: BufFileTell is quite cheap, so not worth trying
652
 
                         * to avoid multiple calls.
 
652
                         * Update read pointers as needed; see API spec above. Note:
 
653
                         * BufFileTell is quite cheap, so not worth trying to avoid
 
654
                         * multiple calls.
653
655
                         */
654
656
                        readptr = state->readptrs;
655
657
                        for (i = 0; i < state->readptrcount; readptr++, i++)
754
756
                                                Assert(!state->truncated);
755
757
                                                return NULL;
756
758
                                        }
757
 
                                        readptr->current--;     /* last returned tuple */
 
759
                                        readptr->current--; /* last returned tuple */
758
760
                                }
759
761
                                if (readptr->current <= 0)
760
762
                                {
996
998
}
997
999
 
998
1000
/*
999
 
 * tuplestore_copy_read_pointer - copy a read pointer's state to another
 
1001
 * tuplestore_copy_read_pointer - copy a read pointer's state to another
1000
1002
 */
1001
1003
void
1002
1004
tuplestore_copy_read_pointer(Tuplestorestate *state,
1015
1017
        if (dptr->eflags != sptr->eflags)
1016
1018
        {
1017
1019
                /* Possible change of overall eflags, so copy and then recompute */
1018
 
                int             eflags;
1019
 
                int             i;
 
1020
                int                     eflags;
 
1021
                int                     i;
1020
1022
 
1021
1023
                *dptr = *sptr;
1022
1024
                eflags = state->readptrs[0].eflags;
1034
1036
                        /* no work */
1035
1037
                        break;
1036
1038
                case TSS_READFILE:
 
1039
 
1037
1040
                        /*
1038
1041
                         * This case is a bit tricky since the active read pointer's
1039
1042
                         * position corresponds to the seek point, not what is in its
1093
1096
        int                     i;
1094
1097
 
1095
1098
        /*
1096
 
         * Truncation is disallowed if any read pointer requires rewind capability.
 
1099
         * Truncation is disallowed if any read pointer requires rewind
 
1100
         * capability.
1097
1101
         */
1098
1102
        if (state->eflags & EXEC_FLAG_REWIND)
1099
1103
                return;
1115
1119
 
1116
1120
        /*
1117
1121
         * Note: you might think we could remove all the tuples before the oldest
1118
 
         * "current", since that one is the next to be returned.  However,
1119
 
         * since tuplestore_gettuple returns a direct pointer to our
1120
 
         * internal copy of the tuple, it's likely that the caller has
1121
 
         * still got the tuple just before "current" referenced in a slot.
1122
 
         * So we keep one extra tuple before the oldest "current".  (Strictly
1123
 
         * speaking, we could require such callers to use the "copy" flag to
1124
 
         * tuplestore_gettupleslot, but for efficiency we allow this one case
1125
 
         * to not use "copy".)
 
1122
         * "current", since that one is the next to be returned.  However, since
 
1123
         * tuplestore_gettuple returns a direct pointer to our internal copy of
 
1124
         * the tuple, it's likely that the caller has still got the tuple just
 
1125
         * before "current" referenced in a slot. So we keep one extra tuple
 
1126
         * before the oldest "current".  (Strictly speaking, we could require such
 
1127
         * callers to use the "copy" flag to tuplestore_gettupleslot, but for
 
1128
         * efficiency we allow this one case to not use "copy".)
1126
1129
         */
1127
1130
        nremove = oldest - 1;
1128
1131
        if (nremove <= 0)
1222
1225
writetup_heap(Tuplestorestate *state, void *tup)
1223
1226
{
1224
1227
        MinimalTuple tuple = (MinimalTuple) tup;
 
1228
 
1225
1229
        /* the part of the MinimalTuple we'll write: */
1226
1230
        char       *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1227
1231
        unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
 
1232
 
1228
1233
        /* total on-disk footprint: */
1229
1234
        unsigned int tuplen = tupbodylen + sizeof(int);
1230
1235
 
1255
1260
        /* read in the tuple proper */
1256
1261
        tuple->t_len = tuplen;
1257
1262
        if (BufFileRead(state->myfile, (void *) tupbody,
1258
 
                                         tupbodylen) != (size_t) tupbodylen)
 
1263
                                        tupbodylen) != (size_t) tupbodylen)
1259
1264
                elog(ERROR, "unexpected end of data");
1260
1265
        if (state->backward)            /* need trailing length word? */
1261
1266
                if (BufFileRead(state->myfile, (void *) &tuplen,