183 #define COPYTUP(state,tup) ((*(state)->copytup) (state, tup))
184 #define WRITETUP(state,tup) ((*(state)->writetup) (state, tup))
185 #define READTUP(state,len) ((*(state)->readtup) (state, len))
186 #define LACKMEM(state) ((state)->availMem < 0)
187 #define USEMEM(state,amt) ((state)->availMem -= (amt))
188 #define FREEMEM(state,amt) ((state)->availMem += (amt))
260 state->eflags = eflags;
261 state->interXact = interXact;
262 state->truncated =
false;
263 state->allowedMem = maxKBytes * 1024L;
265 state->myfile = NULL;
269 state->memtupdeleted = 0;
270 state->memtupcount = 0;
277 state->memtupsize =
Max(16384 /
sizeof(
void *),
280 state->growmemtuples =
true;
285 state->activeptr = 0;
286 state->readptrcount = 1;
287 state->readptrsize = 8;
291 state->readptrs[0].eflags = eflags;
292 state->readptrs[0].eof_reached =
false;
293 state->readptrs[0].current = 0;
327 eflags = randomAccess ?
364 elog(
ERROR,
"too late to call tuplestore_set_eflags");
366 state->readptrs[0].eflags = eflags;
367 for (
i = 1;
i <
state->readptrcount;
i++)
368 eflags |=
state->readptrs[
i].eflags;
369 state->eflags = eflags;
388 if ((
state->eflags | eflags) !=
state->eflags)
389 elog(
ERROR,
"too late to require new tuplestore eflags");
393 if (
state->readptrcount >=
state->readptrsize)
395 int newcnt =
state->readptrsize * 2;
399 state->readptrsize = newcnt;
404 state->readptrs[
state->readptrcount].eflags = eflags;
406 state->eflags |= eflags;
408 return state->readptrcount++;
425 state->myfile = NULL;
426 if (
state->memtuples)
428 for (
i =
state->memtupdeleted; i < state->memtupcount;
i++)
435 state->truncated =
false;
436 state->memtupdeleted = 0;
437 state->memtupcount = 0;
439 readptr =
state->readptrs;
440 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
459 if (
state->memtuples)
461 for (
i =
state->memtupdeleted; i < state->memtupcount;
i++)
478 Assert(ptr >= 0 && ptr < state->readptrcount);
481 if (ptr ==
state->activeptr)
484 readptr = &
state->readptrs[ptr];
487 switch (
state->status)
513 state->writepos_file,
514 state->writepos_offset,
518 errmsg(
"could not seek in tuplestore temporary file")));
528 errmsg(
"could not seek in tuplestore temporary file")));
536 state->activeptr = ptr;
548 return state->tuples;
559 return state->readptrs[
state->activeptr].eof_reached;
581 int memtupsize =
state->memtupsize;
582 int64 memNowUsed =
state->allowedMem -
state->availMem;
585 if (!
state->growmemtuples)
589 if (memNowUsed <= state->availMem)
595 if (memtupsize < INT_MAX / 2)
596 newmemtupsize = memtupsize * 2;
599 newmemtupsize = INT_MAX;
600 state->growmemtuples =
false;
633 grow_ratio = (double)
state->allowedMem / (
double) memNowUsed;
634 if (memtupsize * grow_ratio < INT_MAX)
635 newmemtupsize = (int) (memtupsize * grow_ratio);
637 newmemtupsize = INT_MAX;
640 state->growmemtuples =
false;
644 if (newmemtupsize <= memtupsize)
657 state->growmemtuples =
false;
671 if (
state->availMem < (int64) ((newmemtupsize - memtupsize) *
sizeof(
void *)))
676 state->memtupsize = newmemtupsize;
677 state->memtuples = (
void **)
679 state->memtupsize *
sizeof(
void *));
682 elog(
ERROR,
"unexpected out-of-memory situation in tuplestore");
687 state->growmemtuples =
false;
773 switch (
state->status)
780 readptr =
state->readptrs;
781 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
796 if (
state->memtupcount >=
state->memtupsize - 1)
803 state->memtuples[
state->memtupcount++] = tuple;
841 readptr =
state->readptrs;
842 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
860 if (!
state->readptrs[
state->activeptr].eof_reached)
869 errmsg(
"could not seek in tuplestore temporary file")));
875 readptr =
state->readptrs;
876 for (
i = 0;
i <
state->readptrcount; readptr++,
i++)
912 switch (
state->status)
915 *should_free =
false;
966 &
state->writepos_file, &
state->writepos_offset);
973 errmsg(
"could not seek in tuplestore temporary file")));
1023 -(
long) (tuplen + 2 *
sizeof(
unsigned int)),
1033 -(
long) (tuplen +
sizeof(
unsigned int)),
1037 errmsg(
"could not seek in tuplestore temporary file")));
1054 errmsg(
"could not seek in tuplestore temporary file")));
1059 elog(
ERROR,
"invalid tuplestore state");
1088 if (copy && !should_free)
1144 switch (
state->status)
1181 while (ntuples-- > 0)
1210 for (
i =
state->memtupdeleted;;
i++)
1215 for (
j = 0;
j <
state->readptrcount; readptr++,
j++)
1221 if (
i >=
state->memtupcount)
1225 state->memtupdeleted = 0;
1226 state->memtupcount = 0;
1240 switch (
state->status)
1256 errmsg(
"could not seek in tuplestore temporary file")));
1259 elog(
ERROR,
"invalid tuplestore state");
1269 int srcptr,
int destptr)
1274 Assert(srcptr >= 0 && srcptr < state->readptrcount);
1275 Assert(destptr >= 0 && destptr < state->readptrcount);
1278 if (srcptr == destptr)
1288 eflags =
state->readptrs[0].eflags;
1289 for (
i = 1;
i <
state->readptrcount;
i++)
1290 eflags |=
state->readptrs[
i].eflags;
1291 state->eflags = eflags;
1296 switch (
state->status)
1311 if (destptr ==
state->activeptr)
1316 state->writepos_file,
1317 state->writepos_offset,
1321 errmsg(
"could not seek in tuplestore temporary file")));
1330 errmsg(
"could not seek in tuplestore temporary file")));
1333 else if (srcptr ==
state->activeptr)
1342 elog(
ERROR,
"invalid tuplestore state");
1381 oldest =
state->memtupcount;
1382 for (
i = 0;
i <
state->readptrcount;
i++)
1384 if (!
state->readptrs[
i].eof_reached)
1385 oldest =
Min(oldest,
state->readptrs[
i].current);
1398 nremove = oldest - 1;
1403 Assert(nremove <= state->memtupcount);
1406 for (
i =
state->memtupdeleted;
i < nremove;
i++)
1410 state->memtuples[
i] = NULL;
1412 state->memtupdeleted = nremove;
1415 state->truncated =
true;
1423 if (nremove < state->memtupcount / 8)
1432 if (nremove + 1 ==
state->memtupcount)
1433 state->memtuples[0] =
state->memtuples[nremove];
1435 memmove(
state->memtuples,
state->memtuples + nremove,
1436 (
state->memtupcount - nremove) *
sizeof(
void *));
1438 state->memtupdeleted = 0;
1439 state->memtupcount -= nremove;
1440 for (
i = 0;
i <
state->readptrcount;
i++)
1442 if (!
state->readptrs[
i].eof_reached)
1443 state->readptrs[
i].current -= nremove;
1496 return (
void *) tuple;
1509 unsigned int tuplen = tupbodylen +
sizeof(int);
1513 if (
state->backward)
1523 unsigned int tupbodylen =
len -
sizeof(int);
1530 tuple->
t_len = tuplen;
1532 if (
state->backward)
1534 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)
void BufFileClose(BufFile *file)
elog(ERROR, "%s: %s", p2, msg)
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
MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup)
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
void heap_free_minimal_tuple(MinimalTuple mtup)
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
MinimalTupleData * MinimalTuple
#define MINIMAL_TUPLE_DATA_OFFSET
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Size GetMemoryChunkSpace(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
void * repalloc_huge(void *pointer, Size size)
#define ALLOCSET_SEPARATE_THRESHOLD
#define CHECK_FOR_INTERRUPTS()
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
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)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
#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)
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)
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)