src/backend/utils/sort/logtape.c
/*
 * Seek to an arbitrary position in a logical tape.
 *
 * *Only* a frozen-for-read tape can be seeked.
 *
 * Return value is TRUE if seek successful, FALSE if there isn't that much
 * data in the tape (in which case there's no state change).
 */
Seek to an arbitrary position in a logical tape.
*Only* a frozen-for-read tape can be seeked.

Return value is TRUE if seek successful, FALSE if there isn't that much
data in the tape (in which case there's no state change).
Seek to an arbitrary position in a logical tape . * Only * a frozen - for - read tape can be seeked . Return value is TRUE if seek successful FALSE if there isn ' t that much data in the tape ( in which case there ' s no state change ) .
bool
LogicalTapeSeek(LogicalTapeSet *lts, int tapenum,
				long blocknum, int offset)
{
	LogicalTape *lt;
	Assert(tapenum >= 0 && tapenum < lts->nTapes);
	lt = &lts->tapes[tapenum];
	Assert(lt->frozen);
	Assert(offset >= 0 && offset <= BLCKSZ);
	Assert(lt->buffer_size == BLCKSZ);
	if (blocknum == lt->curBlockNumber && offset <= lt->nbytes)
	{
		lt->pos = offset;
		return true;
	}
	if (blocknum < 0 || blocknum > lt->numFullBlocks ||
		(blocknum == lt->numFullBlocks && offset > lt->lastBlockBytes))
		return false;
	while (lt->curBlockNumber > blocknum)
	{
		long		datablocknum = ltsRecallPrevBlockNum(lts, lt->indirect);
		if (datablocknum == -1L)
			elog(ERROR, "unexpected end of tape");
		if (--lt->curBlockNumber == blocknum)
			ltsReadBlock(lts, datablocknum, (void *) lt->buffer);
	}
	while (lt->curBlockNumber < blocknum)
	{
		long		datablocknum = ltsRecallNextBlockNum(lts, lt->indirect,
														 lt->frozen);
		if (datablocknum == -1L)
			elog(ERROR, "unexpected end of tape");
		if (++lt->curBlockNumber == blocknum)
			ltsReadBlock(lts, datablocknum, (void *) lt->buffer);
	}
	lt->nbytes = (lt->curBlockNumber < lt->numFullBlocks) ?
		BLCKSZ : lt->lastBlockBytes;
	lt->pos = offset;
	return true;
}
bool LogicalTapeSeek ( LogicalTapeSet * lts , int tapenum , long blocknum , int offset ) { LogicalTape * lt ; Assert ( tapenum >= 0 && tapenum < lts -> nTapes ) ; lt = & lts -> tapes [ tapenum ] ; Assert ( lt -> frozen ) ; Assert ( offset >= 0 && offset <= BLCKSZ ) ; Assert ( lt -> buffer_size == BLCKSZ ) ; if ( blocknum == lt -> curBlockNumber && offset <= lt -> nbytes ) { lt -> pos = offset ; return true ; } if ( blocknum < 0 || blocknum > lt -> numFullBlocks || ( blocknum == lt -> numFullBlocks && offset > lt -> lastBlockBytes ) ) return false ; while ( lt -> curBlockNumber > blocknum ) { long datablocknum = ltsRecallPrevBlockNum ( lts , lt -> indirect ) ; if ( datablocknum == -1L ) elog ( ERROR , " " ) ; if ( -- lt -> curBlockNumber == blocknum ) ltsReadBlock ( lts , datablocknum , ( void * ) lt -> buffer ) ; } while ( lt -> curBlockNumber < blocknum ) { long datablocknum = ltsRecallNextBlockNum ( lts , lt -> indirect , lt -> frozen ) ; if ( datablocknum == -1L ) elog ( ERROR , " " ) ; if ( ++ lt -> curBlockNumber == blocknum ) ltsReadBlock ( lts , datablocknum , ( void * ) lt -> buffer ) ; } lt -> nbytes = ( lt -> curBlockNumber < lt -> numFullBlocks ) ? BLCKSZ : lt -> lastBlockBytes ; lt -> pos = offset ; return true ; }
Seek to an arbitrary position in a logical tape.
Seek to an arbitrary position in a logical tape .
/*
	 * Easy case for seek within current block.
	 */ /*
	 * Not-so-easy case.  Figure out whether it's possible at all.
	 */ /*
	 * OK, advance or back up to the target block.  This implementation would
	 * be pretty inefficient for long seeks, but we really aren't expecting
	 * that (a seek over one tuple is typical).
	 */