1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * filemap.h |
4 | * |
5 | * Copyright (c) 2013-2019, PostgreSQL Global Development Group |
6 | *------------------------------------------------------------------------- |
7 | */ |
8 | #ifndef FILEMAP_H |
9 | #define FILEMAP_H |
10 | |
11 | #include "storage/relfilenode.h" |
12 | #include "storage/block.h" |
13 | |
14 | #include "datapagemap.h" |
15 | |
16 | /* |
17 | * For every file found in the local or remote system, we have a file entry |
18 | * which says what we are going to do with the file. For relation files, |
19 | * there is also a page map, marking pages in the file that were changed |
20 | * locally. |
21 | * |
22 | * The enum values are sorted in the order we want actions to be processed. |
23 | */ |
24 | typedef enum |
25 | { |
26 | FILE_ACTION_CREATE, /* create local directory or symbolic link */ |
27 | FILE_ACTION_COPY, /* copy whole file, overwriting if exists */ |
28 | FILE_ACTION_COPY_TAIL, /* copy tail from 'oldsize' to 'newsize' */ |
29 | FILE_ACTION_NONE, /* no action (we might still copy modified |
30 | * blocks based on the parsed WAL) */ |
31 | FILE_ACTION_TRUNCATE, /* truncate local file to 'newsize' bytes */ |
32 | FILE_ACTION_REMOVE /* remove local file / directory / symlink */ |
33 | } file_action_t; |
34 | |
35 | typedef enum |
36 | { |
37 | FILE_TYPE_REGULAR, |
38 | FILE_TYPE_DIRECTORY, |
39 | FILE_TYPE_SYMLINK |
40 | } file_type_t; |
41 | |
42 | typedef struct file_entry_t |
43 | { |
44 | char *path; |
45 | file_type_t type; |
46 | |
47 | file_action_t action; |
48 | |
49 | /* for a regular file */ |
50 | size_t oldsize; |
51 | size_t newsize; |
52 | bool isrelfile; /* is it a relation data file? */ |
53 | |
54 | datapagemap_t pagemap; |
55 | |
56 | /* for a symlink */ |
57 | char *link_target; |
58 | |
59 | struct file_entry_t *next; |
60 | } file_entry_t; |
61 | |
62 | typedef struct filemap_t |
63 | { |
64 | /* |
65 | * New entries are accumulated to a linked list, in process_source_file |
66 | * and process_target_file. |
67 | */ |
68 | file_entry_t *first; |
69 | file_entry_t *last; |
70 | int nlist; /* number of entries currently in list */ |
71 | |
72 | /* |
73 | * After processing all the remote files, the entries in the linked list |
74 | * are moved to this array. After processing local files, too, all the |
75 | * local entries are added to the array by filemap_finalize, and sorted in |
76 | * the final order. After filemap_finalize, all the entries are in the |
77 | * array, and the linked list is empty. |
78 | */ |
79 | file_entry_t **array; |
80 | int narray; /* current length of array */ |
81 | |
82 | /* |
83 | * Summary information. total_size is the total size of the source |
84 | * cluster, and fetch_size is the number of bytes that needs to be copied. |
85 | */ |
86 | uint64 total_size; |
87 | uint64 fetch_size; |
88 | } filemap_t; |
89 | |
90 | extern filemap_t *filemap; |
91 | |
92 | extern void filemap_create(void); |
93 | extern void calculate_totals(void); |
94 | extern void print_filemap(void); |
95 | |
96 | /* Functions for populating the filemap */ |
97 | extern void process_source_file(const char *path, file_type_t type, |
98 | size_t newsize, const char *link_target); |
99 | extern void process_target_file(const char *path, file_type_t type, |
100 | size_t newsize, const char *link_target); |
101 | extern void process_block_change(ForkNumber forknum, RelFileNode rnode, |
102 | BlockNumber blkno); |
103 | extern void filemap_finalize(void); |
104 | |
105 | #endif /* FILEMAP_H */ |
106 | |