184 #define COPYTUP(state,tup) ((*(state)->copytup) (state, tup))
185 #define WRITETUP(state,tup) ((*(state)->writetup) (state, tup))
186 #define READTUP(state,len) ((*(state)->readtup) (state, len))
187 #define LACKMEM(state) ((state)->availMem < 0)
188 #define USEMEM(state,amt) ((state)->availMem -= (amt))
189 #define FREEMEM(state,amt) ((state)->availMem += (amt))
262 state->eflags = eflags;
263 state->interXact = interXact;
264 state->truncated =
false;
265 state->allowedMem = maxKBytes * 1024L;
268 state->myfile = NULL;
279 state->memtupdeleted = 0;
280 state->memtupcount = 0;
287 state->memtupsize =
Max(16384 /
sizeof(
void *),
290 state->growmemtuples =
true;
295 state->activeptr = 0;
296 state->readptrcount = 1;
297 state->readptrsize = 8;
301 state->readptrs[0].eflags = eflags;
302 state->readptrs[0].eof_reached =
false;
303 state->readptrs[0].current = 0;
337 eflags = randomAccess ?
374 elog(
ERROR,
"too late to call tuplestore_set_eflags");
376 state->readptrs[0].eflags = eflags;
377 for (
i = 1;
i <
state->readptrcount;
i++)
378 eflags |=
state->readptrs[
i].eflags;
379 state->eflags = eflags;
398 if ((
state->eflags | eflags) !=
state->eflags)
399 elog(
ERROR,
"too late to require new tuplestore eflags");
403 if (
state->readptrcount >=
state->readptrsize)
405 int newcnt =
state->readptrsize * 2;
409 state->readptrsize = newcnt;
414 state->readptrs[
state->readptrcount].eflags = eflags;
416 state->eflags |= eflags;
418 return state->readptrcount++;
438 state->myfile = NULL;
440 #ifdef USE_ASSERT_CHECKING
442 int64 availMem =
state->availMem;
452 for (
i =
state->memtupdeleted; i < state->memtupcount;
i++)
472 state->truncated =
false;
473 state->memtupdeleted = 0;
474 state->memtupcount = 0;
476 readptr =
state->readptrs;
477 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
510 Assert(ptr >= 0 && ptr < state->readptrcount);
513 if (ptr ==
state->activeptr)
516 readptr = &
state->readptrs[ptr];
519 switch (
state->status)
545 state->writepos_file,
546 state->writepos_offset,
550 errmsg(
"could not seek in tuplestore temporary file")));
560 errmsg(
"could not seek in tuplestore temporary file")));
568 state->activeptr = ptr;
580 return state->tuples;
591 return state->readptrs[
state->activeptr].eof_reached;
613 int memtupsize =
state->memtupsize;
614 int64 memNowUsed =
state->allowedMem -
state->availMem;
617 if (!
state->growmemtuples)
621 if (memNowUsed <= state->availMem)
627 if (memtupsize < INT_MAX / 2)
628 newmemtupsize = memtupsize * 2;
631 newmemtupsize = INT_MAX;
632 state->growmemtuples =
false;
665 grow_ratio = (double)
state->allowedMem / (
double) memNowUsed;
666 if (memtupsize * grow_ratio < INT_MAX)
667 newmemtupsize = (int) (memtupsize * grow_ratio);
669 newmemtupsize = INT_MAX;
672 state->growmemtuples =
false;
676 if (newmemtupsize <= memtupsize)
689 state->growmemtuples =
false;
703 if (
state->availMem < (int64) ((newmemtupsize - memtupsize) *
sizeof(
void *)))
708 state->memtupsize = newmemtupsize;
709 state->memtuples = (
void **)
711 state->memtupsize *
sizeof(
void *));
714 elog(
ERROR,
"unexpected out-of-memory situation in tuplestore");
719 state->growmemtuples =
false;
806 switch (
state->status)
813 readptr =
state->readptrs;
814 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
829 if (
state->memtupcount >=
state->memtupsize - 1)
836 state->memtuples[
state->memtupcount++] = tuple;
883 readptr =
state->readptrs;
884 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
902 if (!
state->readptrs[
state->activeptr].eof_reached)
911 errmsg(
"could not seek in tuplestore temporary file")));
917 readptr =
state->readptrs;
918 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
954 switch (
state->status)
957 *should_free =
false;
1008 &
state->writepos_file, &
state->writepos_offset);
1015 errmsg(
"could not seek in tuplestore temporary file")));
1020 *should_free =
true;
1065 -(
long) (tuplen + 2 *
sizeof(
unsigned int)),
1075 -(
long) (tuplen +
sizeof(
unsigned int)),
1079 errmsg(
"could not seek in tuplestore temporary file")));
1096 errmsg(
"could not seek in tuplestore temporary file")));
1101 elog(
ERROR,
"invalid tuplestore state");
1130 if (copy && !should_free)
1186 switch (
state->status)
1223 while (ntuples-- > 0)
1252 for (
i =
state->memtupdeleted;;
i++)
1257 for (
j = 0;
j <
state->readptrcount; readptr++,
j++)
1263 if (
i >=
state->memtupcount)
1267 state->memtupdeleted = 0;
1268 state->memtupcount = 0;
1282 switch (
state->status)
1298 errmsg(
"could not seek in tuplestore temporary file")));
1301 elog(
ERROR,
"invalid tuplestore state");
1311 int srcptr,
int destptr)
1316 Assert(srcptr >= 0 && srcptr < state->readptrcount);
1317 Assert(destptr >= 0 && destptr < state->readptrcount);
1320 if (srcptr == destptr)
1330 eflags =
state->readptrs[0].eflags;
1331 for (
i = 1;
i <
state->readptrcount;
i++)
1332 eflags |=
state->readptrs[
i].eflags;
1333 state->eflags = eflags;
1338 switch (
state->status)
1353 if (destptr ==
state->activeptr)
1358 state->writepos_file,
1359 state->writepos_offset,
1363 errmsg(
"could not seek in tuplestore temporary file")));
1372 errmsg(
"could not seek in tuplestore temporary file")));
1375 else if (srcptr ==
state->activeptr)
1384 elog(
ERROR,
"invalid tuplestore state");
1423 oldest =
state->memtupcount;
1424 for (
i = 0;
i <
state->readptrcount;
i++)
1426 if (!
state->readptrs[
i].eof_reached)
1427 oldest =
Min(oldest,
state->readptrs[
i].current);
1440 nremove = oldest - 1;
1445 Assert(nremove <= state->memtupcount);
1451 for (
i =
state->memtupdeleted;
i < nremove;
i++)
1455 state->memtuples[
i] = NULL;
1457 state->memtupdeleted = nremove;
1460 state->truncated =
true;
1468 if (nremove < state->memtupcount / 8)
1477 if (nremove + 1 ==
state->memtupcount)
1478 state->memtuples[0] =
state->memtuples[nremove];
1480 memmove(
state->memtuples,
state->memtuples + nremove,
1481 (
state->memtupcount - nremove) *
sizeof(
void *));
1483 state->memtupdeleted = 0;
1484 state->memtupcount -= nremove;
1485 for (
i = 0;
i <
state->readptrcount;
i++)
1487 if (!
state->readptrs[
i].eof_reached)
1488 state->readptrs[
i].current -= nremove;
1530 return state->maxSpace;
1584 return (
void *) tuple;
1597 unsigned int tuplen = tupbodylen +
sizeof(int);
1601 if (
state->backward)
1612 unsigned int tupbodylen =
len -
sizeof(int);
1618 tuple->
t_len = tuplen;
1620 if (
state->backward)
1622 return (
void *) tuple;
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)
#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_space_used(Tuplestorestate *state)
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)
const char * tuplestore_storage_type_name(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)