Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7fdd919

Browse files
committed
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
1 parent 607f8ce commit 7fdd919

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

src/backend/utils/sort/logtape.c

+36-7
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ static long ltsGetFreeBlock(LogicalTapeSet *lts);
201201
static void ltsReleaseBlock(LogicalTapeSet *lts, long blocknum);
202202
static void ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
203203
SharedFileSet *fileset);
204+
static void ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt);
204205

205206

206207
/*
@@ -535,6 +536,27 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
535536
lts->nHoleBlocks = lts->nBlocksAllocated - nphysicalblocks;
536537
}
537538

539+
/*
540+
* Lazily allocate and initialize the read buffer. This avoids waste when many
541+
* tapes are open at once, but not all are active between rewinding and
542+
* reading.
543+
*/
544+
static void
545+
ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt)
546+
{
547+
if (lt->firstBlockNumber != -1L)
548+
{
549+
Assert(lt->buffer_size > 0);
550+
lt->buffer = palloc(lt->buffer_size);
551+
}
552+
553+
/* Read the first block, or reset if tape is empty */
554+
lt->nextBlockNumber = lt->firstBlockNumber;
555+
lt->pos = 0;
556+
lt->nbytes = 0;
557+
ltsReadFillBuffer(lts, lt);
558+
}
559+
538560
/*
539561
* Create a set of logical tapes in a temporary underlying file.
540562
*
@@ -821,15 +843,9 @@ LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum, size_t buffer_size)
821843
lt->buffer_size = 0;
822844
if (lt->firstBlockNumber != -1L)
823845
{
824-
lt->buffer = palloc(buffer_size);
846+
/* the buffer is lazily allocated, but set the size here */
825847
lt->buffer_size = buffer_size;
826848
}
827-
828-
/* Read the first block, or reset if tape is empty */
829-
lt->nextBlockNumber = lt->firstBlockNumber;
830-
lt->pos = 0;
831-
lt->nbytes = 0;
832-
ltsReadFillBuffer(lts, lt);
833849
}
834850

835851
/*
@@ -878,6 +894,9 @@ LogicalTapeRead(LogicalTapeSet *lts, int tapenum,
878894
lt = &lts->tapes[tapenum];
879895
Assert(!lt->writing);
880896

897+
if (lt->buffer == NULL)
898+
ltsInitReadBuffer(lts, lt);
899+
881900
while (size > 0)
882901
{
883902
if (lt->pos >= lt->nbytes)
@@ -1015,6 +1034,9 @@ LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum, size_t size)
10151034
Assert(lt->frozen);
10161035
Assert(lt->buffer_size == BLCKSZ);
10171036

1037+
if (lt->buffer == NULL)
1038+
ltsInitReadBuffer(lts, lt);
1039+
10181040
/*
10191041
* Easy case for seek within current block.
10201042
*/
@@ -1087,6 +1109,9 @@ LogicalTapeSeek(LogicalTapeSet *lts, int tapenum,
10871109
Assert(offset >= 0 && offset <= TapeBlockPayloadSize);
10881110
Assert(lt->buffer_size == BLCKSZ);
10891111

1112+
if (lt->buffer == NULL)
1113+
ltsInitReadBuffer(lts, lt);
1114+
10901115
if (blocknum != lt->curBlockNumber)
10911116
{
10921117
ltsReadBlock(lts, blocknum, (void *) lt->buffer);
@@ -1114,6 +1139,10 @@ LogicalTapeTell(LogicalTapeSet *lts, int tapenum,
11141139

11151140
Assert(tapenum >= 0 && tapenum < lts->nTapes);
11161141
lt = &lts->tapes[tapenum];
1142+
1143+
if (lt->buffer == NULL)
1144+
ltsInitReadBuffer(lts, lt);
1145+
11171146
Assert(lt->offsetBlockNumber == 0L);
11181147

11191148
/* With a larger buffer, 'pos' wouldn't be the same as offset within page */

0 commit comments

Comments
 (0)