mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
Logical Tape Set: lazily allocate read buffer.
The write buffer was already lazily-allocated, so this is more symmetric. It also means that a freshly-rewound tape (whether for reading or writing) is not consuming memory for the buffer. Discussion: https://postgr.es/m/97c46a59c27f3c38e486ca170fcbc618d97ab049.camel%40j-davis.com
This commit is contained in:
parent
607f8ce74d
commit
7fdd919ae7
@ -201,6 +201,7 @@ static long ltsGetFreeBlock(LogicalTapeSet *lts);
|
|||||||
static void ltsReleaseBlock(LogicalTapeSet *lts, long blocknum);
|
static void ltsReleaseBlock(LogicalTapeSet *lts, long blocknum);
|
||||||
static void ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
|
static void ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
|
||||||
SharedFileSet *fileset);
|
SharedFileSet *fileset);
|
||||||
|
static void ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -535,6 +536,27 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
|
|||||||
lts->nHoleBlocks = lts->nBlocksAllocated - nphysicalblocks;
|
lts->nHoleBlocks = lts->nBlocksAllocated - nphysicalblocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lazily allocate and initialize the read buffer. This avoids waste when many
|
||||||
|
* tapes are open at once, but not all are active between rewinding and
|
||||||
|
* reading.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt)
|
||||||
|
{
|
||||||
|
if (lt->firstBlockNumber != -1L)
|
||||||
|
{
|
||||||
|
Assert(lt->buffer_size > 0);
|
||||||
|
lt->buffer = palloc(lt->buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the first block, or reset if tape is empty */
|
||||||
|
lt->nextBlockNumber = lt->firstBlockNumber;
|
||||||
|
lt->pos = 0;
|
||||||
|
lt->nbytes = 0;
|
||||||
|
ltsReadFillBuffer(lts, lt);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a set of logical tapes in a temporary underlying file.
|
* Create a set of logical tapes in a temporary underlying file.
|
||||||
*
|
*
|
||||||
@ -821,15 +843,9 @@ LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum, size_t buffer_size)
|
|||||||
lt->buffer_size = 0;
|
lt->buffer_size = 0;
|
||||||
if (lt->firstBlockNumber != -1L)
|
if (lt->firstBlockNumber != -1L)
|
||||||
{
|
{
|
||||||
lt->buffer = palloc(buffer_size);
|
/* the buffer is lazily allocated, but set the size here */
|
||||||
lt->buffer_size = buffer_size;
|
lt->buffer_size = buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the first block, or reset if tape is empty */
|
|
||||||
lt->nextBlockNumber = lt->firstBlockNumber;
|
|
||||||
lt->pos = 0;
|
|
||||||
lt->nbytes = 0;
|
|
||||||
ltsReadFillBuffer(lts, lt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -878,6 +894,9 @@ LogicalTapeRead(LogicalTapeSet *lts, int tapenum,
|
|||||||
lt = <s->tapes[tapenum];
|
lt = <s->tapes[tapenum];
|
||||||
Assert(!lt->writing);
|
Assert(!lt->writing);
|
||||||
|
|
||||||
|
if (lt->buffer == NULL)
|
||||||
|
ltsInitReadBuffer(lts, lt);
|
||||||
|
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
if (lt->pos >= lt->nbytes)
|
if (lt->pos >= lt->nbytes)
|
||||||
@ -1015,6 +1034,9 @@ LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum, size_t size)
|
|||||||
Assert(lt->frozen);
|
Assert(lt->frozen);
|
||||||
Assert(lt->buffer_size == BLCKSZ);
|
Assert(lt->buffer_size == BLCKSZ);
|
||||||
|
|
||||||
|
if (lt->buffer == NULL)
|
||||||
|
ltsInitReadBuffer(lts, lt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Easy case for seek within current block.
|
* Easy case for seek within current block.
|
||||||
*/
|
*/
|
||||||
@ -1087,6 +1109,9 @@ LogicalTapeSeek(LogicalTapeSet *lts, int tapenum,
|
|||||||
Assert(offset >= 0 && offset <= TapeBlockPayloadSize);
|
Assert(offset >= 0 && offset <= TapeBlockPayloadSize);
|
||||||
Assert(lt->buffer_size == BLCKSZ);
|
Assert(lt->buffer_size == BLCKSZ);
|
||||||
|
|
||||||
|
if (lt->buffer == NULL)
|
||||||
|
ltsInitReadBuffer(lts, lt);
|
||||||
|
|
||||||
if (blocknum != lt->curBlockNumber)
|
if (blocknum != lt->curBlockNumber)
|
||||||
{
|
{
|
||||||
ltsReadBlock(lts, blocknum, (void *) lt->buffer);
|
ltsReadBlock(lts, blocknum, (void *) lt->buffer);
|
||||||
@ -1114,6 +1139,10 @@ LogicalTapeTell(LogicalTapeSet *lts, int tapenum,
|
|||||||
|
|
||||||
Assert(tapenum >= 0 && tapenum < lts->nTapes);
|
Assert(tapenum >= 0 && tapenum < lts->nTapes);
|
||||||
lt = <s->tapes[tapenum];
|
lt = <s->tapes[tapenum];
|
||||||
|
|
||||||
|
if (lt->buffer == NULL)
|
||||||
|
ltsInitReadBuffer(lts, lt);
|
||||||
|
|
||||||
Assert(lt->offsetBlockNumber == 0L);
|
Assert(lt->offsetBlockNumber == 0L);
|
||||||
|
|
||||||
/* With a larger buffer, 'pos' wouldn't be the same as offset within page */
|
/* With a larger buffer, 'pos' wouldn't be the same as offset within page */
|
||||||
|
Loading…
Reference in New Issue
Block a user