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

Lines changed: 36 additions & 7 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy