@ -191,8 +191,8 @@ struct LogicalTapeSet
Size freeBlocksLen ; /* current allocated length of freeBlocks[] */
/* The array of logical tapes. */
int nTapes ; /* # of logical tapes in set */
LogicalTape tapes [ FLEXIBLE_ARRAY_MEMBER ] ; /* has nTapes nentries */
int nTapes ; /* # of logical tapes in set */
LogicalTape * tapes ; /* has nTapes nentries */
} ;
static void ltsWriteBlock ( LogicalTapeSet * lts , long blocknum , void * buffer ) ;
@ -201,6 +201,7 @@ static long ltsGetFreeBlock(LogicalTapeSet *lts);
static void ltsReleaseBlock ( LogicalTapeSet * lts , long blocknum ) ;
static void ltsConcatWorkerTapes ( LogicalTapeSet * lts , TapeShare * shared ,
SharedFileSet * fileset ) ;
static void ltsInitTape ( LogicalTape * lt ) ;
static void ltsInitReadBuffer ( LogicalTapeSet * lts , LogicalTape * lt ) ;
@ -536,6 +537,27 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
lts - > nHoleBlocks = lts - > nBlocksAllocated - nphysicalblocks ;
}
/*
* Initialize per - tape struct . Note we allocate the I / O buffer lazily .
*/
static void
ltsInitTape ( LogicalTape * lt )
{
lt - > writing = true ;
lt - > frozen = false ;
lt - > dirty = false ;
lt - > firstBlockNumber = - 1L ;
lt - > curBlockNumber = - 1L ;
lt - > nextBlockNumber = - 1L ;
lt - > offsetBlockNumber = 0L ;
lt - > buffer = NULL ;
lt - > buffer_size = 0 ;
/* palloc() larger than MaxAllocSize would fail */
lt - > max_size = MaxAllocSize ;
lt - > pos = 0 ;
lt - > nbytes = 0 ;
}
/*
* 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
@ -579,15 +601,13 @@ LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset,
int worker )
{
LogicalTapeSet * lts ;
LogicalTape * lt ;
int i ;
/*
* Create top - level struct including per - tape LogicalTape structs .
*/
Assert ( ntapes > 0 ) ;
lts = ( LogicalTapeSet * ) palloc ( offsetof ( LogicalTapeSet , tapes ) +
ntapes * sizeof ( LogicalTape ) ) ;
lts = ( LogicalTapeSet * ) palloc ( sizeof ( LogicalTapeSet ) ) ;
lts - > nBlocksAllocated = 0L ;
lts - > nBlocksWritten = 0L ;
lts - > nHoleBlocks = 0L ;
@ -596,30 +616,10 @@ LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset,
lts - > freeBlocks = ( long * ) palloc ( lts - > freeBlocksLen * sizeof ( long ) ) ;
lts - > nFreeBlocks = 0 ;
lts - > nTapes = ntapes ;
lts - > tapes = ( LogicalTape * ) palloc ( ntapes * sizeof ( LogicalTape ) ) ;
/*
* Initialize per - tape structs . Note we allocate the I / O buffer and the
* first block for a tape only when it is first actually written to . This
* avoids wasting memory space when tuplesort . c overestimates the number
* of tapes needed .
*/
for ( i = 0 ; i < ntapes ; i + + )
{
lt = & lts - > tapes [ i ] ;
lt - > writing = true ;
lt - > frozen = false ;
lt - > dirty = false ;
lt - > firstBlockNumber = - 1L ;
lt - > curBlockNumber = - 1L ;
lt - > nextBlockNumber = - 1L ;
lt - > offsetBlockNumber = 0L ;
lt - > buffer = NULL ;
lt - > buffer_size = 0 ;
/* palloc() larger than MaxAllocSize would fail */
lt - > max_size = MaxAllocSize ;
lt - > pos = 0 ;
lt - > nbytes = 0 ;
}
ltsInitTape ( & lts - > tapes [ i ] ) ;
/*
* Create temp BufFile storage as required .
@ -1004,6 +1004,25 @@ LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum, TapeShare *share)
}
}
/*
* Add additional tapes to this tape set . Not intended to be used when any
* tapes are frozen .
*/
void
LogicalTapeSetExtend ( LogicalTapeSet * lts , int nAdditional )
{
int i ;
int nTapesOrig = lts - > nTapes ;
lts - > nTapes + = nAdditional ;
lts - > tapes = ( LogicalTape * ) repalloc (
lts - > tapes , lts - > nTapes * sizeof ( LogicalTape ) ) ;
for ( i = nTapesOrig ; i < lts - > nTapes ; i + + )
ltsInitTape ( & lts - > tapes [ i ] ) ;
}
/*
* Backspace the tape a given number of bytes . ( We also support a more
* general seek interface , see below . )