* Create a set of logical tapes in a temporary underlying file. * * Each tape is initialized in write state. Serial callers pass ntapes, * NULL argument for shared, and -1 for worker. Parallel worker callers * pass ntapes, a shared file handle, NULL shared argument, and their own * worker number. Leader callers, which claim shared worker tapes here, * must supply non-sentinel values for
| 687 | * infrastructure that may be lifted in the future. |
| 688 | */ |
| 689 | LogicalTapeSet * |
| 690 | LogicalTapeSetCreate(int ntapes, bool preallocate, TapeShare *shared, |
| 691 | SharedFileSet *fileset, int worker) |
| 692 | { |
| 693 | LogicalTapeSet *lts; |
| 694 | int i; |
| 695 | |
| 696 | /* |
| 697 | * Create top-level struct including per-tape LogicalTape structs. |
| 698 | */ |
| 699 | Assert(ntapes > 0); |
| 700 | lts = (LogicalTapeSet *) palloc(sizeof(LogicalTapeSet)); |
| 701 | lts->nBlocksAllocated = 0L; |
| 702 | lts->nBlocksWritten = 0L; |
| 703 | lts->nHoleBlocks = 0L; |
| 704 | lts->forgetFreeSpace = false; |
| 705 | lts->freeBlocksLen = 32; /* reasonable initial guess */ |
| 706 | lts->freeBlocks = (long *) palloc(lts->freeBlocksLen * sizeof(long)); |
| 707 | lts->nFreeBlocks = 0; |
| 708 | lts->enable_prealloc = preallocate; |
| 709 | lts->nTapes = ntapes; |
| 710 | lts->tapes = (LogicalTape *) palloc(ntapes * sizeof(LogicalTape)); |
| 711 | |
| 712 | for (i = 0; i < ntapes; i++) |
| 713 | ltsInitTape(<s->tapes[i]); |
| 714 | |
| 715 | /* |
| 716 | * Create temp BufFile storage as required. |
| 717 | * |
| 718 | * Leader concatenates worker tapes, which requires special adjustment to |
| 719 | * final tapeset data. Things are simpler for the worker case and the |
| 720 | * serial case, though. They are generally very similar -- workers use a |
| 721 | * shared fileset, whereas serial sorts use a conventional serial BufFile. |
| 722 | */ |
| 723 | if (shared) |
| 724 | ltsConcatWorkerTapes(lts, shared, fileset); |
| 725 | else if (fileset) |
| 726 | { |
| 727 | char filename[MAXPGPATH]; |
| 728 | workfile_set *work_set; |
| 729 | |
| 730 | pg_itoa(worker, filename); |
| 731 | work_set = workfile_mgr_create_set("LogicalTape", filename, false /* hold pin */); |
| 732 | lts->pfile = BufFileCreateShared(fileset, filename, work_set); |
| 733 | } |
| 734 | else |
| 735 | lts->pfile = BufFileCreateTemp("LogicalTape", false); |
| 736 | |
| 737 | return lts; |
| 738 | } |
| 739 | |
| 740 | /* |
| 741 | * Close a logical tape set and release all resources. |