1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

walmethods.c/h: Make WalWriteMethod more object-oriented.

Normally when we use object-oriented programming techniques, we
provide a pointer to an object and then some way of looking up the
associated table of callbacks, but walmethods.c/h took the alternative
approach of providing only a pointer to the table of callbacks and
thus imposed the artificial restriction that there could only ever be
one object of each type, so that the callbacks could find it via a
global variable. That doesn't seem like the right idea, so revise the
approach.

Each callback which does not already have an argument of type
Walfile * now takes a pointer to the relevant WalWriteMethod *
so that these callbacks need not rely on there being only one
object of each type.

Freeing a WalWriteMethod is now performed via a callback provided
for that purpose rather than requiring the caller to know which
WAL method they want to free.

Discussion: http://postgr.es/m/CA+TgmoZS0Kw98fOoAcGz8B9iDhdqB4Be4e=vDZaJZ5A-xMYBqA@mail.gmail.com
This commit is contained in:
Robert Haas
2022-09-19 12:53:46 -04:00
parent c35ba141de
commit ebfb814f7c
5 changed files with 354 additions and 313 deletions

View File

@@ -16,6 +16,7 @@ typedef struct WalWriteMethod WalWriteMethod;
typedef struct
{
WalWriteMethod *wwmethod;
off_t currpos;
char *pathname;
/*
@@ -34,16 +35,9 @@ typedef enum
} WalCloseMethod;
/*
* A WalWriteMethod structure represents the different methods used
* to write the streaming WAL as it's received.
*
* All methods that have a failure return indicator will set state
* allowing the getlasterror() method to return a suitable message.
* Commonly, errno is this state (or part of it); so callers must take
* care not to clobber errno between a failed method call and use of
* getlasterror() to retrieve the message.
* Table of callbacks for a WalWriteMethod.
*/
struct WalWriteMethod
typedef struct WalWriteMethodOps
{
/*
* Open a target file. Returns Walfile, or NULL if open failed. If a temp
@@ -51,7 +45,7 @@ struct WalWriteMethod
* automatically renamed in close(). If pad_to_size is specified, the file
* will be padded with NUL up to that size, if supported by the Walmethod.
*/
Walfile *(*open_for_write) (const char *pathname, const char *temp_suffix, size_t pad_to_size);
Walfile *(*open_for_write) (WalWriteMethod *wwmethod, const char *pathname, const char *temp_suffix, size_t pad_to_size);
/*
* Close an open Walfile, using one or more methods for handling automatic
@@ -60,19 +54,16 @@ struct WalWriteMethod
int (*close) (Walfile *f, WalCloseMethod method);
/* Check if a file exist */
bool (*existsfile) (const char *pathname);
bool (*existsfile) (WalWriteMethod *wwmethod, const char *pathname);
/* Return the size of a file, or -1 on failure. */
ssize_t (*get_file_size) (const char *pathname);
ssize_t (*get_file_size) (WalWriteMethod *wwmethod, const char *pathname);
/*
* Return the name of the current file to work on in pg_malloc()'d string,
* without the base directory. This is useful for logging.
*/
char *(*get_file_name) (const char *pathname, const char *temp_suffix);
/* Returns the compression method */
pg_compress_algorithm (*compression_algorithm) (void);
char *(*get_file_name) (WalWriteMethod *wwmethod, const char *pathname, const char *temp_suffix);
/*
* Write count number of bytes to the file, and return the number of bytes
@@ -91,10 +82,37 @@ struct WalWriteMethod
* close/write/sync of shared resources succeeded, otherwise returns false
* (but the resources are still closed).
*/
bool (*finish) (void);
bool (*finish) (WalWriteMethod *wwmethod);
/* Return a text for the last error in this Walfile */
const char *(*getlasterror) (void);
/*
* Free subsidiary data associated with the WalWriteMethod, and the
* WalWriteMethod itself.
*/
void (*free) (WalWriteMethod *wwmethod);
} WalWriteMethodOps;
/*
* A WalWriteMethod structure represents a way of writing streaming WAL as
* it's received.
*
* All methods that have a failure return indicator will set lasterrstring
* or lasterrno (the former takes precedence) so that the caller can signal
* a suitable error.
*/
struct WalWriteMethod
{
const WalWriteMethodOps *ops;
pg_compress_algorithm compression_algorithm;
int compression_level;
bool sync;
const char *lasterrstring; /* if set, takes precedence over lasterrno */
int lasterrno;
/*
* MORE DATA FOLLOWS AT END OF STRUCT
*
* Each WalWriteMethod is expected to embed this as the first member of
* a larger struct with method-specific fields following.
*/
};
/*
@@ -111,6 +129,4 @@ WalWriteMethod *CreateWalTarMethod(const char *tarbase,
pg_compress_algorithm compression_algo,
int compression, bool sync);
/* Cleanup routines for previously-created methods */
void FreeWalDirectoryMethod(void);
void FreeWalTarMethod(void);
const char *GetLastWalMethodError(WalWriteMethod *wwmethod);