* the already-read length of the stored tuple. Create a palloc'd copy,
* initialize tuple/datum1/isnull1 in the target SortTuple struct, and
* decrease state->availMem by the amount of memory space consumed.
+ * (See batchUsed notes for details on how memory is handled when
+ * incremental accounting is abandoned.)
*/
void (*readtup) (Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len);
+ /*
+ * Function to move a caller tuple. This is usually implemented as a
+ * memmove() shim, but function may also perform additional fix-up of
+ * caller tuple where needed. Batch memory support requires the
+ * movement of caller tuples from one location in memory to another.
+ */
+ void (*movetup) (void *dest, void *src, unsigned int len);
+
/*
* This array holds the tuples now in sort memory. If we are in state
* INITIAL, the tuples are in no particular order; if we are in state
#define COPYTUP(state,stup,tup) ((*(state)->copytup) (state, stup, tup))
#define WRITETUP(state,tape,stup) ((*(state)->writetup) (state, tape, stup))
#define READTUP(state,stup,tape,len) ((*(state)->readtup) (state, stup, tape, len))
+#define MOVETUP(dest,src,len) ((*(state)->movetup) (dest, src, len))
#define LACKMEM(state) ((state)->availMem < 0 && !(state)->batchUsed)
#define USEMEM(state,amt) ((state)->availMem -= (amt))
#define FREEMEM(state,amt) ((state)->availMem += (amt))
SortTuple *stup);
static void readtup_heap(Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len);
+static void movetup_heap(void *dest, void *src, unsigned int len);
static int comparetup_cluster(const SortTuple *a, const SortTuple *b,
Tuplesortstate *state);
static void copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup);
SortTuple *stup);
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len);
+static void movetup_cluster(void *dest, void *src, unsigned int len);
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b,
Tuplesortstate *state);
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b,
SortTuple *stup);
static void readtup_index(Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len);
+static void movetup_index(void *dest, void *src, unsigned int len);
static int comparetup_datum(const SortTuple *a, const SortTuple *b,
Tuplesortstate *state);
static void copytup_datum(Tuplesortstate *state, SortTuple *stup, void *tup);
SortTuple *stup);
static void readtup_datum(Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len);
+static void movetup_datum(void *dest, void *src, unsigned int len);
static void free_sort_tuple(Tuplesortstate *state, SortTuple *stup);
/*
state->copytup = copytup_heap;
state->writetup = writetup_heap;
state->readtup = readtup_heap;
+ state->movetup = movetup_heap;
state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
state->abbrevNext = 10;
state->copytup = copytup_cluster;
state->writetup = writetup_cluster;
state->readtup = readtup_cluster;
+ state->movetup = movetup_cluster;
state->abbrevNext = 10;
state->indexInfo = BuildIndexInfo(indexRel);
state->copytup = copytup_index;
state->writetup = writetup_index;
state->readtup = readtup_index;
+ state->movetup = movetup_index;
state->abbrevNext = 10;
state->heapRel = heapRel;
state->copytup = copytup_index;
state->writetup = writetup_index;
state->readtup = readtup_index;
+ state->movetup = movetup_index;
state->heapRel = heapRel;
state->indexRel = indexRel;
state->copytup = copytup_datum;
state->writetup = writetup_datum;
state->readtup = readtup_datum;
+ state->movetup = movetup_datum;
state->abbrevNext = 10;
state->datumType = datumType;
*/
tupLen = state->mergecurrent[srcTape] - state->mergetail[srcTape];
state->mergecurrent[srcTape] = state->mergetuples[srcTape];
- memmove(state->mergecurrent[srcTape], state->mergetail[srcTape],
+ MOVETUP(state->mergecurrent[srcTape], state->mergetail[srcTape],
tupLen);
/* Make SortTuple at top of the merge heap point to new tuple */
tuplen = state->mergecurrent[srcTape] - state->mergetail[srcTape];
rtup->tuple = MemoryContextAlloc(state->sortcontext, tuplen);
- memcpy(rtup->tuple, oldTuple, tuplen);
+ MOVETUP(rtup->tuple, oldTuple, tuplen);
*should_free = true;
}
&stup->isnull1);
}
+static void
+movetup_heap(void *dest, void *src, unsigned int len)
+{
+ memmove(dest, src, len);
+}
+
/*
* Routines specialized for the CLUSTER case (HeapTuple data, with
* comparisons per a btree index definition)
&stup->isnull1);
}
+static void
+movetup_cluster(void *dest, void *src, unsigned int len)
+{
+ HeapTuple tuple;
+
+ memmove(dest, src, len);
+
+ /* Repoint the HeapTupleData header */
+ tuple = (HeapTuple) dest;
+ tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
+}
+
/*
* Routines specialized for IndexTuple case
&stup->isnull1);
}
+static void
+movetup_index(void *dest, void *src, unsigned int len)
+{
+ memmove(dest, src, len);
+}
+
/*
* Routines specialized for DatumTuple case
*/
&tuplen, sizeof(tuplen));
}
+static void
+movetup_datum(void *dest, void *src, unsigned int len)
+{
+ memmove(dest, src, len);
+}
+
/*
* Convenience routine to free a tuple previously loaded into sort memory
*/