185 #define COPYTUP(state,tup) ((*(state)->copytup) (state, tup))
186 #define WRITETUP(state,tup) ((*(state)->writetup) (state, tup))
187 #define READTUP(state,len) ((*(state)->readtup) (state, len))
188 #define LACKMEM(state) ((state)->availMem < 0)
189 #define USEMEM(state,amt) ((state)->availMem -= (amt))
190 #define FREEMEM(state,amt) ((state)->availMem += (amt))
263 state->eflags = eflags;
264 state->interXact = interXact;
265 state->truncated =
false;
266 state->usedDisk =
false;
268 state->allowedMem = maxKBytes * 1024L;
270 state->myfile = NULL;
281 state->memtupdeleted = 0;
282 state->memtupcount = 0;
289 state->memtupsize =
Max(16384 /
sizeof(
void *),
292 state->growmemtuples =
true;
297 state->activeptr = 0;
298 state->readptrcount = 1;
299 state->readptrsize = 8;
303 state->readptrs[0].eflags = eflags;
304 state->readptrs[0].eof_reached =
false;
305 state->readptrs[0].current = 0;
339 eflags = randomAccess ?
376 elog(
ERROR,
"too late to call tuplestore_set_eflags");
378 state->readptrs[0].eflags = eflags;
379 for (
i = 1;
i <
state->readptrcount;
i++)
380 eflags |=
state->readptrs[
i].eflags;
381 state->eflags = eflags;
400 if ((
state->eflags | eflags) !=
state->eflags)
401 elog(
ERROR,
"too late to require new tuplestore eflags");
405 if (
state->readptrcount >=
state->readptrsize)
407 int newcnt =
state->readptrsize * 2;
411 state->readptrsize = newcnt;
416 state->readptrs[
state->readptrcount].eflags = eflags;
418 state->eflags |= eflags;
420 return state->readptrcount++;
440 state->myfile = NULL;
442 #ifdef USE_ASSERT_CHECKING
454 for (
i =
state->memtupdeleted; i < state->memtupcount;
i++)
474 state->truncated =
false;
475 state->memtupdeleted = 0;
476 state->memtupcount = 0;
478 readptr =
state->readptrs;
479 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
512 Assert(ptr >= 0 && ptr < state->readptrcount);
515 if (ptr ==
state->activeptr)
518 readptr = &
state->readptrs[ptr];
521 switch (
state->status)
547 state->writepos_file,
548 state->writepos_offset,
552 errmsg(
"could not seek in tuplestore temporary file")));
562 errmsg(
"could not seek in tuplestore temporary file")));
570 state->activeptr = ptr;
582 return state->tuples;
593 return state->readptrs[
state->activeptr].eof_reached;
615 int memtupsize =
state->memtupsize;
619 if (!
state->growmemtuples)
623 if (memNowUsed <= state->availMem)
629 if (memtupsize < INT_MAX / 2)
630 newmemtupsize = memtupsize * 2;
633 newmemtupsize = INT_MAX;
634 state->growmemtuples =
false;
667 grow_ratio = (double)
state->allowedMem / (
double) memNowUsed;
668 if (memtupsize * grow_ratio < INT_MAX)
669 newmemtupsize = (int) (memtupsize * grow_ratio);
671 newmemtupsize = INT_MAX;
674 state->growmemtuples =
false;
678 if (newmemtupsize <= memtupsize)
691 state->growmemtuples =
false;
705 if (
state->availMem < (
int64) ((newmemtupsize - memtupsize) *
sizeof(
void *)))
710 state->memtupsize = newmemtupsize;
711 state->memtuples = (
void **)
713 state->memtupsize *
sizeof(
void *));
716 elog(
ERROR,
"unexpected out-of-memory situation in tuplestore");
721 state->growmemtuples =
false;
808 switch (
state->status)
815 readptr =
state->readptrs;
816 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
831 if (
state->memtupcount >=
state->memtupsize - 1)
838 state->memtuples[
state->memtupcount++] = tuple;
893 readptr =
state->readptrs;
894 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
912 if (!
state->readptrs[
state->activeptr].eof_reached)
921 errmsg(
"could not seek in tuplestore temporary file")));
927 readptr =
state->readptrs;
928 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
964 switch (
state->status)
967 *should_free =
false;
1018 &
state->writepos_file, &
state->writepos_offset);
1025 errmsg(
"could not seek in tuplestore temporary file")));
1030 *should_free =
true;
1075 -(
long) (tuplen + 2 *
sizeof(
unsigned int)),
1085 -(
long) (tuplen +
sizeof(
unsigned int)),
1089 errmsg(
"could not seek in tuplestore temporary file")));
1106 errmsg(
"could not seek in tuplestore temporary file")));
1111 elog(
ERROR,
"invalid tuplestore state");
1140 if (copy && !should_free)
1196 switch (
state->status)
1233 while (ntuples-- > 0)
1262 for (
i =
state->memtupdeleted;;
i++)
1267 for (
j = 0;
j <
state->readptrcount; readptr++,
j++)
1273 if (
i >=
state->memtupcount)
1277 state->memtupdeleted = 0;
1278 state->memtupcount = 0;
1292 switch (
state->status)
1308 errmsg(
"could not seek in tuplestore temporary file")));
1311 elog(
ERROR,
"invalid tuplestore state");
1321 int srcptr,
int destptr)
1326 Assert(srcptr >= 0 && srcptr < state->readptrcount);
1327 Assert(destptr >= 0 && destptr < state->readptrcount);
1330 if (srcptr == destptr)
1340 eflags =
state->readptrs[0].eflags;
1341 for (
i = 1;
i <
state->readptrcount;
i++)
1342 eflags |=
state->readptrs[
i].eflags;
1343 state->eflags = eflags;
1348 switch (
state->status)
1363 if (destptr ==
state->activeptr)
1368 state->writepos_file,
1369 state->writepos_offset,
1373 errmsg(
"could not seek in tuplestore temporary file")));
1382 errmsg(
"could not seek in tuplestore temporary file")));
1385 else if (srcptr ==
state->activeptr)
1394 elog(
ERROR,
"invalid tuplestore state");
1433 oldest =
state->memtupcount;
1434 for (
i = 0;
i <
state->readptrcount;
i++)
1436 if (!
state->readptrs[
i].eof_reached)
1437 oldest =
Min(oldest,
state->readptrs[
i].current);
1450 nremove = oldest - 1;
1455 Assert(nremove <= state->memtupcount);
1461 for (
i =
state->memtupdeleted;
i < nremove;
i++)
1465 state->memtuples[
i] = NULL;
1467 state->memtupdeleted = nremove;
1470 state->truncated =
true;
1478 if (nremove < state->memtupcount / 8)
1487 if (nremove + 1 ==
state->memtupcount)
1488 state->memtuples[0] =
state->memtuples[nremove];
1490 memmove(
state->memtuples,
state->memtuples + nremove,
1491 (
state->memtupcount - nremove) *
sizeof(
void *));
1493 state->memtupdeleted = 0;
1494 state->memtupcount -= nremove;
1495 for (
i = 0;
i <
state->readptrcount;
i++)
1497 if (!
state->readptrs[
i].eof_reached)
1498 state->readptrs[
i].current -= nremove;
1522 state->usedDisk =
true;
1538 if (
state->usedDisk)
1539 *max_storage_type =
"Disk";
1541 *max_storage_type =
"Memory";
1543 *max_space =
state->maxSpace;
1608 unsigned int tuplen = tupbodylen +
sizeof(int);
1612 if (
state->backward)
1622 unsigned int tupbodylen =
len -
sizeof(int);
1628 tuple->
t_len = tuplen;
1630 if (
state->backward)
void PrepareTempTablespaces(void)
static Datum values[MAXATTR]
void BufFileReadExact(BufFile *file, void *ptr, size_t size)
void BufFileTell(BufFile *file, int *fileno, off_t *offset)
BufFile * BufFileCreateTemp(bool interXact)
void BufFileWrite(BufFile *file, const void *ptr, size_t size)
size_t BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK)
int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
int64 BufFileSize(BufFile *file)
void BufFileClose(BufFile *file)
#define Assert(condition)
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
#define EXEC_FLAG_BACKWARD
MemoryContext GenerationContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup)
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_free_minimal_tuple(MinimalTuple mtup)
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
MinimalTupleData * MinimalTuple
#define MINIMAL_TUPLE_DATA_OFFSET
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
Size GetMemoryChunkSpace(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
void MemoryContextDelete(MemoryContext context)
void * repalloc_huge(void *pointer, Size size)
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SEPARATE_THRESHOLD
#define CHECK_FOR_INTERRUPTS()
MemoryContextSwitchTo(old_ctx)
ResourceOwner CurrentResourceOwner
void(* writetup)(Tuplestorestate *state, void *tup)
#define WRITETUP(state, tup)
void tuplestore_get_stats(Tuplestorestate *state, char **max_storage_type, int64 *max_space)
#define READTUP(state, len)
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
#define USEMEM(state, amt)
static void writetup_heap(Tuplestorestate *state, void *tup)
void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)
static void * copytup_heap(Tuplestorestate *state, void *tup)
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
#define COPYTUP(state, tup)
void tuplestore_clear(Tuplestorestate *state)
static bool grow_memtuples(Tuplestorestate *state)
static void * tuplestore_gettuple(Tuplestorestate *state, bool forward, bool *should_free)
#define FREEMEM(state, amt)
static Tuplestorestate * tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
int64 tuplestore_tuple_count(Tuplestorestate *state)
void tuplestore_rescan(Tuplestorestate *state)
int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)
void tuplestore_trim(Tuplestorestate *state)
void tuplestore_copy_read_pointer(Tuplestorestate *state, int srcptr, int destptr)
bool tuplestore_advance(Tuplestorestate *state, bool forward)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
static void * readtup_heap(Tuplestorestate *state, unsigned int len)
bool tuplestore_in_memory(Tuplestorestate *state)
void tuplestore_end(Tuplestorestate *state)
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
bool tuplestore_ateof(Tuplestorestate *state)
static void dumptuples(Tuplestorestate *state)
static void tuplestore_updatemax(Tuplestorestate *state)
void tuplestore_set_eflags(Tuplestorestate *state, int eflags)
bool tuplestore_skiptuples(Tuplestorestate *state, int64 ntuples, bool forward)
static unsigned int getlen(Tuplestorestate *state, bool eofOK)
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)