@@ -210,6 +210,7 @@ struct LogicalTapeSet
210
210
long * freeBlocks ; /* resizable array holding minheap */
211
211
long nFreeBlocks ; /* # of currently free blocks */
212
212
Size freeBlocksLen ; /* current allocated length of freeBlocks[] */
213
+ bool enable_prealloc ; /* preallocate write blocks? */
213
214
214
215
/* The array of logical tapes. */
215
216
int nTapes ; /* # of logical tapes in set */
@@ -218,6 +219,7 @@ struct LogicalTapeSet
218
219
219
220
static void ltsWriteBlock (LogicalTapeSet * lts , long blocknum , void * buffer );
220
221
static void ltsReadBlock (LogicalTapeSet * lts , long blocknum , void * buffer );
222
+ static long ltsGetBlock (LogicalTapeSet * lts , LogicalTape * lt );
221
223
static long ltsGetFreeBlock (LogicalTapeSet * lts );
222
224
static long ltsGetPreallocBlock (LogicalTapeSet * lts , LogicalTape * lt );
223
225
static void ltsReleaseBlock (LogicalTapeSet * lts , long blocknum );
@@ -240,12 +242,8 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
240
242
* that's past the current end of file, fill the space between the current
241
243
* end of file and the target block with zeros.
242
244
*
243
- * This should happen rarely, otherwise you are not writing very
244
- * sequentially. In current use, this only happens when the sort ends
245
- * writing a run, and switches to another tape. The last block of the
246
- * previous tape isn't flushed to disk until the end of the sort, so you
247
- * get one-block hole, where the last block of the previous tape will
248
- * later go.
245
+ * This can happen either when tapes preallocate blocks; or for the last
246
+ * block of a tape which might not have been flushed.
249
247
*
250
248
* Note that BufFile concatenation can leave "holes" in BufFile between
251
249
* worker-owned block ranges. These are tracked for reporting purposes
@@ -371,8 +369,20 @@ parent_offset(unsigned long i)
371
369
}
372
370
373
371
/*
374
- * Select the lowest currently unused block by taking the first element from
375
- * the freelist min heap.
372
+ * Get the next block for writing.
373
+ */
374
+ static long
375
+ ltsGetBlock (LogicalTapeSet * lts , LogicalTape * lt )
376
+ {
377
+ if (lts -> enable_prealloc )
378
+ return ltsGetPreallocBlock (lts , lt );
379
+ else
380
+ return ltsGetFreeBlock (lts );
381
+ }
382
+
383
+ /*
384
+ * Select the lowest currently unused block from the tape set's global free
385
+ * list min heap.
376
386
*/
377
387
static long
378
388
ltsGetFreeBlock (LogicalTapeSet * lts )
@@ -428,7 +438,8 @@ ltsGetFreeBlock(LogicalTapeSet *lts)
428
438
429
439
/*
430
440
* Return the lowest free block number from the tape's preallocation list.
431
- * Refill the preallocation list if necessary.
441
+ * Refill the preallocation list with blocks from the tape set's free list if
442
+ * necessary.
432
443
*/
433
444
static long
434
445
ltsGetPreallocBlock (LogicalTapeSet * lts , LogicalTape * lt )
@@ -669,8 +680,8 @@ ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt)
669
680
* infrastructure that may be lifted in the future.
670
681
*/
671
682
LogicalTapeSet *
672
- LogicalTapeSetCreate (int ntapes , TapeShare * shared , SharedFileSet * fileset ,
673
- int worker )
683
+ LogicalTapeSetCreate (int ntapes , bool preallocate , TapeShare * shared ,
684
+ SharedFileSet * fileset , int worker )
674
685
{
675
686
LogicalTapeSet * lts ;
676
687
int i ;
@@ -687,6 +698,7 @@ LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset,
687
698
lts -> freeBlocksLen = 32 ; /* reasonable initial guess */
688
699
lts -> freeBlocks = (long * ) palloc (lts -> freeBlocksLen * sizeof (long ));
689
700
lts -> nFreeBlocks = 0 ;
701
+ lts -> enable_prealloc = preallocate ;
690
702
lts -> nTapes = ntapes ;
691
703
lts -> tapes = (LogicalTape * ) palloc (ntapes * sizeof (LogicalTape ));
692
704
@@ -780,7 +792,7 @@ LogicalTapeWrite(LogicalTapeSet *lts, int tapenum,
780
792
Assert (lt -> firstBlockNumber == -1 );
781
793
Assert (lt -> pos == 0 );
782
794
783
- lt -> curBlockNumber = ltsGetPreallocBlock (lts , lt );
795
+ lt -> curBlockNumber = ltsGetBlock (lts , lt );
784
796
lt -> firstBlockNumber = lt -> curBlockNumber ;
785
797
786
798
TapeBlockGetTrailer (lt -> buffer )-> prev = -1L ;
@@ -804,7 +816,7 @@ LogicalTapeWrite(LogicalTapeSet *lts, int tapenum,
804
816
* First allocate the next block, so that we can store it in the
805
817
* 'next' pointer of this block.
806
818
*/
807
- nextBlockNumber = ltsGetPreallocBlock (lts , lt );
819
+ nextBlockNumber = ltsGetBlock (lts , lt );
808
820
809
821
/* set the next-pointer and dump the current block. */
810
822
TapeBlockGetTrailer (lt -> buffer )-> next = nextBlockNumber ;
0 commit comments