src/backend/utils/sort/logtape.c
/*
 * Rewind logical tape and switch from writing to reading.
 *
 * The tape must currently be in writing state, or "frozen" in read state.
 *
 * 'buffer_size' specifies how much memory to use for the read buffer.  It
 * does not include the memory needed for the indirect blocks.  Regardless
 * of the argument, the actual amount of memory used is between BLCKSZ and
 * MaxAllocSize, and is a multiple of BLCKSZ.  The given value is rounded
 * down and truncated to fit those constraints, if necessary.  If the tape
 * is frozen, the 'buffer_size' argument is ignored, and a small BLCKSZ byte
 * buffer is used.
 */
Rewind logical tape and switch from writing to reading.
The tape must currently be in writing state, or "frozen" in read state.

'buffer_size' specifies how much memory to use for the read buffer.  It
does not include the memory needed for the indirect blocks.  Regardless
of the argument, the actual amount of memory used is between BLCKSZ and
MaxAllocSize, and is a multiple of BLCKSZ.  The given value is rounded
down and truncated to fit those constraints, if necessary.  If the tape
is frozen, the 'buffer_size' argument is ignored, and a small BLCKSZ byte
buffer is used.
Rewind logical tape and switch from writing to reading . The tape must currently be in writing state or " frozen " in read state . ' buffer_size ' specifies how much memory to use for the read buffer . It does not include the memory needed for the indirect blocks . Regardless of the argument the actual amount of memory used is between BLCKSZ and MaxAllocSize and is a multiple of BLCKSZ . The given value is rounded down and truncated to fit those constraints if necessary . If the tape is frozen the ' buffer_size ' argument is ignored and a small BLCKSZ byte buffer is used .
void
LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum, size_t buffer_size)
{
	LogicalTape *lt;
	long		datablocknum;
	Assert(tapenum >= 0 && tapenum < lts->nTapes);
	lt = &lts->tapes[tapenum];
	if (lt->frozen)
		buffer_size = BLCKSZ;
	else
	{
		if (buffer_size < BLCKSZ)
			buffer_size = BLCKSZ;
		if (buffer_size > MaxAllocSize)
			buffer_size = MaxAllocSize;
		buffer_size -= buffer_size % BLCKSZ;
	}
	if (lt->writing)
	{
		if (lt->dirty)
			ltsDumpBuffer(lts, lt);
		lt->lastBlockBytes = lt->nbytes;
		lt->writing = false;
		datablocknum = ltsRewindIndirectBlock(lts, lt->indirect, false);
	}
	else
	{
		Assert(lt->frozen);
		datablocknum = ltsRewindFrozenIndirectBlock(lts, lt->indirect);
	}
	if (lt->buffer)
		pfree(lt->buffer);
	lt->buffer = NULL;
	lt->buffer_size = 0;
	if (datablocknum != -1L)
	{
		lt->buffer = palloc(buffer_size);
		lt->buffer_size = buffer_size;
	}
	lt->curBlockNumber = 0L;
	lt->pos = 0;
	lt->nbytes = 0;
	if (datablocknum != -1L)
		ltsReadFillBuffer(lts, lt, datablocknum);
}
void LogicalTapeRewindForRead ( LogicalTapeSet * lts , int tapenum , size_t buffer_size ) { LogicalTape * lt ; long datablocknum ; Assert ( tapenum >= 0 && tapenum < lts -> nTapes ) ; lt = & lts -> tapes [ tapenum ] ; if ( lt -> frozen ) buffer_size = BLCKSZ ; else { if ( buffer_size < BLCKSZ ) buffer_size = BLCKSZ ; if ( buffer_size > MaxAllocSize ) buffer_size = MaxAllocSize ; buffer_size -= buffer_size % BLCKSZ ; } if ( lt -> writing ) { if ( lt -> dirty ) ltsDumpBuffer ( lts , lt ) ; lt -> lastBlockBytes = lt -> nbytes ; lt -> writing = false ; datablocknum = ltsRewindIndirectBlock ( lts , lt -> indirect , false ) ; } else { Assert ( lt -> frozen ) ; datablocknum = ltsRewindFrozenIndirectBlock ( lts , lt -> indirect ) ; } if ( lt -> buffer ) pfree ( lt -> buffer ) ; lt -> buffer = NULL ; lt -> buffer_size = 0 ; if ( datablocknum != -1L ) { lt -> buffer = palloc ( buffer_size ) ; lt -> buffer_size = buffer_size ; } lt -> curBlockNumber = 0L ; lt -> pos = 0 ; lt -> nbytes = 0 ; if ( datablocknum != -1L ) ltsReadFillBuffer ( lts , lt , datablocknum ) ; }
Rewind logical tape and switch from writing to reading.
Rewind logical tape and switch from writing to reading .
/*
	 * Round and cap buffer_size if needed.
	 */ /* need at least one block */ /*
		 * palloc() larger than MaxAllocSize would fail (a multi-gigabyte
		 * buffer is unlikely to be helpful, anyway)
		 */ /* round down to BLCKSZ boundary */ /*
		 * Completion of a write phase.  Flush last partial data block, flush
		 * any partial indirect blocks, rewind for normal (destructive) read.
		 */ /*
		 * This is only OK if tape is frozen; we rewind for (another) read
		 * pass.
		 */ /* Allocate a read buffer (unless the tape is empty) */ /* Read the first block, or reset if tape is empty */