1/*-------------------------------------------------------------------------
2 *
3 * logtape.h
4 * Management of "logical tapes" within temporary files.
5 *
6 * See logtape.c for explanations.
7 *
8 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 * src/include/utils/logtape.h
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#ifndef LOGTAPE_H
17#define LOGTAPE_H
18
19#include "storage/sharedfileset.h"
20
21/* LogicalTapeSet is an opaque type whose details are not known outside logtape.c. */
22
23typedef struct LogicalTapeSet LogicalTapeSet;
24
25/*
26 * The approach tuplesort.c takes to parallel external sorts is that workers,
27 * whose state is almost the same as independent serial sorts, are made to
28 * produce a final materialized tape of sorted output in all cases. This is
29 * frozen, just like any case requiring a final materialized tape. However,
30 * there is one difference, which is that freezing will also export an
31 * underlying shared fileset BufFile for sharing. Freezing produces TapeShare
32 * metadata for the worker when this happens, which is passed along through
33 * shared memory to leader.
34 *
35 * The leader process can then pass an array of TapeShare metadata (one per
36 * worker participant) to LogicalTapeSetCreate(), alongside a handle to a
37 * shared fileset, which is sufficient to construct a new logical tapeset that
38 * consists of each of the tapes materialized by workers.
39 *
40 * Note that while logtape.c does create an empty leader tape at the end of the
41 * tapeset in the leader case, it can never be written to due to a restriction
42 * in the shared buffile infrastructure.
43 */
44typedef struct TapeShare
45{
46 /*
47 * Currently, all the leader process needs is the location of the
48 * materialized tape's first block.
49 */
50 long firstblocknumber;
51} TapeShare;
52
53/*
54 * prototypes for functions in logtape.c
55 */
56
57extern LogicalTapeSet *LogicalTapeSetCreate(int ntapes, TapeShare *shared,
58 SharedFileSet *fileset, int worker);
59extern void LogicalTapeSetClose(LogicalTapeSet *lts);
60extern void LogicalTapeSetForgetFreeSpace(LogicalTapeSet *lts);
61extern size_t LogicalTapeRead(LogicalTapeSet *lts, int tapenum,
62 void *ptr, size_t size);
63extern void LogicalTapeWrite(LogicalTapeSet *lts, int tapenum,
64 void *ptr, size_t size);
65extern void LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum,
66 size_t buffer_size);
67extern void LogicalTapeRewindForWrite(LogicalTapeSet *lts, int tapenum);
68extern void LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum,
69 TapeShare *share);
70extern size_t LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum,
71 size_t size);
72extern void LogicalTapeSeek(LogicalTapeSet *lts, int tapenum,
73 long blocknum, int offset);
74extern void LogicalTapeTell(LogicalTapeSet *lts, int tapenum,
75 long *blocknum, int *offset);
76extern long LogicalTapeSetBlocks(LogicalTapeSet *lts);
77
78#endif /* LOGTAPE_H */
79