| 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 | |