Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb34aa33

Browse files
committed
Modify logtape.c so that the initial LogicalTapeSetCreate call only
allocates the control data. The per-tape buffers are allocated onlyon first use. This saves memory in situations where tuplesort.coverestimates the number of tapes needed (ie, there are fewer runsthan tapes). Also, this makes legitimate the coding in inittapes()that includes tape buffer space in the maximum-memory calculation:when inittapes runs, we've already expended the whole allowed memoryon tuple storage, and so we'd better not allocate all the tape buffersuntil we've flushed some tuples out of memory.
1 parentdf700e6 commitb34aa33

File tree

1 file changed

+57
-26
lines changed

1 file changed

+57
-26
lines changed

‎src/backend/utils/sort/logtape.c

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
* Portions Copyright (c) 1994, Regents of the University of California
6565
*
6666
* IDENTIFICATION
67-
* $PostgreSQL: pgsql/src/backend/utils/sort/logtape.c,v 1.17 2005/10/18 22:59:37 tgl Exp $
67+
* $PostgreSQL: pgsql/src/backend/utils/sort/logtape.c,v 1.18 2006/02/19 05:58:36 tgl Exp $
6868
*
6969
*-------------------------------------------------------------------------
7070
*/
@@ -124,10 +124,10 @@ typedef struct LogicalTape
124124
* we do need the relative block number so we can detect end-of-tape while
125125
* reading.
126126
*/
127+
char*buffer;/* physical buffer (separately palloc'd) */
127128
longcurBlockNumber;/* this block's logical blk# within tape */
128129
intpos;/* next read/write position in buffer */
129130
intnbytes;/* total # of valid bytes in buffer */
130-
charbuffer[BLCKSZ];
131131
}LogicalTape;
132132

133133
/*
@@ -156,7 +156,7 @@ struct LogicalTapeSet
156156
* is of length nTapes.
157157
*/
158158
intnTapes;/* # of logical tapes in set */
159-
LogicalTape*tapes[1];/* must be last in struct! */
159+
LogicalTapetapes[1];/* must be last in struct! */
160160
};
161161

162162
staticvoidltsWriteBlock(LogicalTapeSet*lts,longblocknum,void*buffer);
@@ -327,6 +327,10 @@ ltsRewindIndirectBlock(LogicalTapeSet *lts,
327327
IndirectBlock*indirect,
328328
boolfreezing)
329329
{
330+
/* Handle case of never-written-to tape */
331+
if (indirect==NULL)
332+
return-1L;
333+
330334
/* Insert sentinel if block is not full */
331335
if (indirect->nextSlot<BLOCKS_PER_INDIR_BLOCK)
332336
indirect->ptrs[indirect->nextSlot]=-1L;
@@ -366,6 +370,10 @@ static long
366370
ltsRewindFrozenIndirectBlock(LogicalTapeSet*lts,
367371
IndirectBlock*indirect)
368372
{
373+
/* Handle case of never-written-to tape */
374+
if (indirect==NULL)
375+
return-1L;
376+
369377
/*
370378
* If block is not topmost, recurse to obtain address of first block in
371379
* this hierarchy level. Read that one in.
@@ -399,6 +407,10 @@ ltsRecallNextBlockNum(LogicalTapeSet *lts,
399407
IndirectBlock*indirect,
400408
boolfrozen)
401409
{
410+
/* Handle case of never-written-to tape */
411+
if (indirect==NULL)
412+
return-1L;
413+
402414
if (indirect->nextSlot >=BLOCKS_PER_INDIR_BLOCK||
403415
indirect->ptrs[indirect->nextSlot]==-1L)
404416
{
@@ -432,6 +444,10 @@ static long
432444
ltsRecallPrevBlockNum(LogicalTapeSet*lts,
433445
IndirectBlock*indirect)
434446
{
447+
/* Handle case of never-written-to tape */
448+
if (indirect==NULL)
449+
return-1L;
450+
435451
if (indirect->nextSlot <=1)
436452
{
437453
longindirblock;
@@ -467,12 +483,12 @@ LogicalTapeSetCreate(int ntapes)
467483
inti;
468484

469485
/*
470-
* Create top-level struct. First LogicalTapepointer is already counted
471-
* in sizeof(LogicalTapeSet).
486+
* Create top-level struct including per-tape LogicalTapestructs.
487+
*First LogicalTape struct is already countedin sizeof(LogicalTapeSet).
472488
*/
473489
Assert(ntapes>0);
474490
lts= (LogicalTapeSet*)palloc(sizeof(LogicalTapeSet)+
475-
(ntapes-1)*sizeof(LogicalTape*));
491+
(ntapes-1)*sizeof(LogicalTape));
476492
lts->pfile=BufFileCreateTemp(false);
477493
lts->nFileBlocks=0L;
478494
lts->freeBlocksLen=32;/* reasonable initial guess */
@@ -481,20 +497,21 @@ LogicalTapeSetCreate(int ntapes)
481497
lts->nTapes=ntapes;
482498

483499
/*
484-
* Create per-tape structs, including first-level indirect blocks.
500+
* Initialize per-tape structs. Note we allocate the I/O buffer and
501+
* first-level indirect block for a tape only when it is first actually
502+
* written to. This avoids wasting memory space when tuplesort.c
503+
* overestimates the number of tapes needed.
485504
*/
486505
for (i=0;i<ntapes;i++)
487506
{
488-
lt= (LogicalTape*)palloc(sizeof(LogicalTape));
489-
lts->tapes[i]=lt;
490-
lt->indirect= (IndirectBlock*)palloc(sizeof(IndirectBlock));
491-
lt->indirect->nextSlot=0;
492-
lt->indirect->nextup=NULL;
507+
lt=&lts->tapes[i];
508+
lt->indirect=NULL;
493509
lt->writing= true;
494510
lt->frozen= false;
495511
lt->dirty= false;
496512
lt->numFullBlocks=0L;
497513
lt->lastBlockBytes=0;
514+
lt->buffer=NULL;
498515
lt->curBlockNumber=0L;
499516
lt->pos=0;
500517
lt->nbytes=0;
@@ -516,13 +533,14 @@ LogicalTapeSetClose(LogicalTapeSet *lts)
516533
BufFileClose(lts->pfile);
517534
for (i=0;i<lts->nTapes;i++)
518535
{
519-
lt=lts->tapes[i];
536+
lt=&lts->tapes[i];
520537
for (ib=lt->indirect;ib!=NULL;ib=nextib)
521538
{
522539
nextib=ib->nextup;
523540
pfree(ib);
524541
}
525-
pfree(lt);
542+
if (lt->buffer)
543+
pfree(lt->buffer);
526544
}
527545
pfree(lts->freeBlocks);
528546
pfree(lts);
@@ -556,9 +574,19 @@ LogicalTapeWrite(LogicalTapeSet *lts, int tapenum,
556574
size_tnthistime;
557575

558576
Assert(tapenum >=0&&tapenum<lts->nTapes);
559-
lt=lts->tapes[tapenum];
577+
lt=&lts->tapes[tapenum];
560578
Assert(lt->writing);
561579

580+
/* Allocate data buffer and first indirect block on first write */
581+
if (lt->buffer==NULL)
582+
lt->buffer= (char*)palloc(BLCKSZ);
583+
if (lt->indirect==NULL)
584+
{
585+
lt->indirect= (IndirectBlock*)palloc(sizeof(IndirectBlock));
586+
lt->indirect->nextSlot=0;
587+
lt->indirect->nextup=NULL;
588+
}
589+
562590
while (size>0)
563591
{
564592
if (lt->pos >=BLCKSZ)
@@ -606,7 +634,7 @@ LogicalTapeRewind(LogicalTapeSet *lts, int tapenum, bool forWrite)
606634
longdatablocknum;
607635

608636
Assert(tapenum >=0&&tapenum<lts->nTapes);
609-
lt=lts->tapes[tapenum];
637+
lt=&lts->tapes[tapenum];
610638

611639
if (!forWrite)
612640
{
@@ -660,13 +688,16 @@ LogicalTapeRewind(LogicalTapeSet *lts, int tapenum, bool forWrite)
660688

661689
Assert(!lt->writing&& !lt->frozen);
662690
/* Must truncate the indirect-block hierarchy down to one level. */
663-
for (ib=lt->indirect->nextup;ib!=NULL;ib=nextib)
691+
if (lt->indirect)
664692
{
665-
nextib=ib->nextup;
666-
pfree(ib);
693+
for (ib=lt->indirect->nextup;ib!=NULL;ib=nextib)
694+
{
695+
nextib=ib->nextup;
696+
pfree(ib);
697+
}
698+
lt->indirect->nextSlot=0;
699+
lt->indirect->nextup=NULL;
667700
}
668-
lt->indirect->nextSlot=0;
669-
lt->indirect->nextup=NULL;
670701
lt->writing= true;
671702
lt->dirty= false;
672703
lt->numFullBlocks=0L;
@@ -691,7 +722,7 @@ LogicalTapeRead(LogicalTapeSet *lts, int tapenum,
691722
size_tnthistime;
692723

693724
Assert(tapenum >=0&&tapenum<lts->nTapes);
694-
lt=lts->tapes[tapenum];
725+
lt=&lts->tapes[tapenum];
695726
Assert(!lt->writing);
696727

697728
while (size>0)
@@ -749,7 +780,7 @@ LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum)
749780
longdatablocknum;
750781

751782
Assert(tapenum >=0&&tapenum<lts->nTapes);
752-
lt=lts->tapes[tapenum];
783+
lt=&lts->tapes[tapenum];
753784
Assert(lt->writing);
754785

755786
/*
@@ -793,7 +824,7 @@ LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum, size_t size)
793824
intnewpos;
794825

795826
Assert(tapenum >=0&&tapenum<lts->nTapes);
796-
lt=lts->tapes[tapenum];
827+
lt=&lts->tapes[tapenum];
797828
Assert(lt->frozen);
798829

799830
/*
@@ -858,7 +889,7 @@ LogicalTapeSeek(LogicalTapeSet *lts, int tapenum,
858889
LogicalTape*lt;
859890

860891
Assert(tapenum >=0&&tapenum<lts->nTapes);
861-
lt=lts->tapes[tapenum];
892+
lt=&lts->tapes[tapenum];
862893
Assert(lt->frozen);
863894
Assert(offset >=0&&offset <=BLCKSZ);
864895

@@ -921,7 +952,7 @@ LogicalTapeTell(LogicalTapeSet *lts, int tapenum,
921952
LogicalTape*lt;
922953

923954
Assert(tapenum >=0&&tapenum<lts->nTapes);
924-
lt=lts->tapes[tapenum];
955+
lt=&lts->tapes[tapenum];
925956
*blocknum=lt->curBlockNumber;
926957
*offset=lt->pos;
927958
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp