v2-0007-Introduce-bbarchiver-abstraction.patch
application/octet-stream
Filename: v2-0007-Introduce-bbarchiver-abstraction.patch
Type: application/octet-stream
Part: 8
Message:
Re: refactoring basebackup.c
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0007
Subject: Introduce bbarchiver abstraction.
| File | + | − |
|---|---|---|
| src/backend/replication/basebackup_archiver.c | 119 | 0 |
| src/backend/replication/Makefile | 1 | 0 |
| src/include/replication/basebackup_archiver.h | 195 | 0 |
From 9890dbd31017f8421b2ea33b22f4484c9a75ac86 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Fri, 1 May 2020 16:43:16 -0400
Subject: [PATCH v2 07/11] Introduce bbarchiver abstraction.
---
src/backend/replication/Makefile | 1 +
src/backend/replication/basebackup_archiver.c | 119 +++++++++++
src/include/replication/basebackup_archiver.h | 195 ++++++++++++++++++
3 files changed, 315 insertions(+)
create mode 100644 src/backend/replication/basebackup_archiver.c
create mode 100644 src/include/replication/basebackup_archiver.h
diff --git a/src/backend/replication/Makefile b/src/backend/replication/Makefile
index 7de4f82882..aacccd350d 100644
--- a/src/backend/replication/Makefile
+++ b/src/backend/replication/Makefile
@@ -17,6 +17,7 @@ override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS)
OBJS = \
backup_manifest.o \
basebackup.o \
+ basebackup_archiver.o \
basebackup_libpq.o \
basebackup_progress.o \
basebackup_sink.o \
diff --git a/src/backend/replication/basebackup_archiver.c b/src/backend/replication/basebackup_archiver.c
new file mode 100644
index 0000000000..045a8a088e
--- /dev/null
+++ b/src/backend/replication/basebackup_archiver.c
@@ -0,0 +1,119 @@
+/*-------------------------------------------------------------------------
+ *
+ * basebackup_archiver.c
+ * general supporting code for basebackup archiver implementations
+ *
+ * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/backend/replication/basebackup_archiver.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "replication/basebackup_archiver.h"
+
+/* Pass begin_tablespace callback to next bbarchiver. */
+void
+bbarchiver_forward_begin_tablespace(bbarchiver *archiver, tablespaceinfo *tsinfo)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_begin_tablespace(archiver->bba_next, tsinfo);
+}
+
+/* Pass end_tablespace callback to next bbarchiver. */
+void
+bbarchiver_forward_end_tablespace(bbarchiver *archiver)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_end_tablespace(archiver->bba_next);
+}
+
+/* Pass begin_file callback to next bbarchiver. */
+void
+bbarchiver_forward_begin_file(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_begin_file(archiver->bba_next, relative_path, statbuf);
+}
+
+/* Pass file_contents callback to next bbarchiver. */
+void
+bbarchiver_forward_file_contents(bbarchiver *archiver, const char *data, size_t len)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_file_contents(archiver->bba_next, data, len);
+}
+
+/* Pass end_file callback to next bbarchiver. */
+void
+bbarchiver_forward_end_file(bbarchiver *archiver)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_end_file(archiver->bba_next);
+}
+
+/* Pass directory callback to next bbarchiver. */
+void
+bbarchiver_forward_directory(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_directory(archiver->bba_next, relative_path, statbuf);
+}
+
+/* Pass symbolic_link callback to next bbarchiver. */
+void
+bbarchiver_forward_symbolic_link(bbarchiver *archiver, const char *relative_path,
+ const char *linktarget, struct stat *statbuf)
+{
+ Assert(archiver->bba_next != NULL);
+ bbarchiver_symbolic_link(archiver->bba_next, relative_path, linktarget, statbuf);
+}
+
+/* Ignore begin_tablespace callback. */
+void
+bbarchiver_noop_begin_tablespace(bbarchiver *archiver, tablespaceinfo *tsinfo)
+{
+ /* Do nothing */
+}
+
+/* Ignore end_tablespace callback. */
+void
+bbarchiver_noop_end_tablespace(bbarchiver *archiver)
+{
+ /* Do nothing */
+}
+
+/* Ignore begin_file callback. */
+void
+bbarchiver_noop_begin_file(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf)
+{
+ /* Do nothing */
+}
+
+/* Ignore end_file callback. */
+void
+bbarchiver_noop_end_file(bbarchiver *archiver)
+{
+ /* Do nothing */
+}
+
+/* Ignore directory callback. */
+void
+bbarchiver_noop_directory(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf)
+{
+ /* Do nothing */
+}
+
+/* Ignore symbolic_link callback. */
+void
+bbarchiver_noop_symbolic_link(bbarchiver *archiver, const char *relative_path,
+ const char *linktarget, struct stat *statbuf)
+{
+ /* Do nothing */
+}
diff --git a/src/include/replication/basebackup_archiver.h b/src/include/replication/basebackup_archiver.h
new file mode 100644
index 0000000000..fce0afa167
--- /dev/null
+++ b/src/include/replication/basebackup_archiver.h
@@ -0,0 +1,195 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbarchiver.h
+ * iterate over files, directories, and symbolic links encountered as
+ * part of the base backup process
+ *
+ * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group
+ *
+ * src/include/replication/bbarchiver.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef BASEBACKUP_ARCHIVER_H
+#define BASEBACKUP_ARCHIVER_H
+
+#include <sys/stat.h>
+
+#include "replication/basebackup.h"
+#include "replication/basebackup_sink.h"
+
+struct bbarchiver;
+struct bbarchiver_ops;
+typedef struct bbarchiver bbarchiver;
+typedef struct bbarchiver_ops bbarchiver_ops;
+
+/*
+ * Common data for any type of basebackup archiver.
+ *
+ * 'bba_ops' is the relevant callback table.
+ *
+ * 'bba_next' is a pointer to another bbarchiver to which this bbarchiver is
+ * forwarding some or all operations.
+ *
+ * If a barchiver needs to store additional state, it can allocate a larger
+ * structure whose first element is a bbarchiver.
+ */
+struct bbarchiver
+{
+ const bbarchiver_ops *bba_ops;
+ bbarchiver *bba_next;
+};
+
+/*
+ * Callbacks for a backup archiver.
+ *
+ * Except as otherwise noted, all of these callbacks are required. If a particular
+ * callback just needs to forward the call to archiver->bba_next, use
+ * bbarchiver_forward_<callback_name> as the callback. If a particular (required)
+ * callback doesn't need to do anything at all, use bbarchiver_noop_<callback_name>
+ * as the callback.
+ *
+ * Callers should always invoke these callbacks via the bbarchiver_*
+ * inline functions rather than calling them directly.
+ */
+struct bbarchiver_ops
+{
+ /* These callbacks are invoked just before and after visiting each tablespace. */
+ void (*begin_tablespace)(bbarchiver *archiver, tablespaceinfo *tsinfo);
+ void (*end_tablespace)(bbarchiver *archiver);
+
+ /* This callback is invoked each time we begin visiting a plain file. */
+ void (*begin_file)(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf);
+
+ /*
+ * This callback is invoked one or more times for each plain file, with the
+ * contents of the file passed to it chunk by chunk.
+ *
+ * It is optional. If NULL, the file is not read.
+ */
+ void (*file_contents)(bbarchiver *archiver, const char *data,
+ size_t len);
+
+ /* This callback is invoked each time we finish visiting a plain file. */
+ void (*end_file)(bbarchiver *archiver);
+
+ /* This method gets called each time we visit a directory. */
+ void (*directory)(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf);
+
+ /* This method gets called each time we visit a symbolic link. */
+ void (*symbolic_link)(bbarchiver *archiver, const char *relative_path,
+ const char *linktarget, struct stat *statbuf);
+};
+
+/* Dummy callbacks for when a bbarchiver wants to forward operations. */
+extern void bbarchiver_forward_begin_tablespace(bbarchiver *archiver,
+ tablespaceinfo *tsinfo);
+extern void bbarchiver_forward_end_tablespace(bbarchiver *archiver);
+extern void bbarchiver_forward_begin_file(bbarchiver *archiver,
+ const char *relative_path,
+ struct stat *statbuf);
+extern void bbarchiver_forward_file_contents(bbarchiver *archiver,
+ const char *data, size_t len);
+extern void bbarchiver_forward_end_file(bbarchiver *archiver);
+extern void bbarchiver_forward_directory(bbarchiver *archiver,
+ const char *relative_path,
+ struct stat *statbuf);
+extern void bbarchiver_forward_symbolic_link(bbarchiver *archiver,
+ const char *relative_path,
+ const char *linktarget,
+ struct stat *statbuf);
+
+/* Dummy callbacks for when a bbarchiver wants to do nothing. */
+extern void bbarchiver_noop_begin_tablespace(bbarchiver *archiver,
+ tablespaceinfo *tsinfo);
+extern void bbarchiver_noop_end_tablespace(bbarchiver *archiver);
+extern void bbarchiver_noop_begin_file(bbarchiver *archiver,
+ const char *relative_path,
+ struct stat *statbuf);
+/* if there's nothing to do for file contents, omit callback! */
+extern void bbarchiver_noop_end_file(bbarchiver *archiver);
+extern void bbarchiver_noop_directory(bbarchiver *archiver,
+ const char *relative_path,
+ struct stat *statbuf);
+extern void bbarchiver_noop_symbolic_link(bbarchiver *archiver,
+ const char *relative_path,
+ const char *linktarget,
+ struct stat *statbuf);
+
+/* Begin visiting a tablespace. */
+static inline void
+bbarchiver_begin_tablespace(bbarchiver *archiver, tablespaceinfo *tsinfo)
+{
+ Assert(archiver->bba_ops->begin_tablespace != NULL);
+ archiver->bba_ops->begin_tablespace(archiver, tsinfo);
+}
+
+/* Finish visiting a tablespace. */
+static inline void
+bbarchiver_end_tablespace(bbarchiver *archiver)
+{
+ Assert(archiver->bba_ops->end_tablespace != NULL);
+ archiver->bba_ops->end_tablespace(archiver);
+}
+
+/* Begin visiting a plain file. */
+static inline void
+bbarchiver_begin_file(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf)
+{
+ Assert(archiver->bba_ops->begin_file != NULL);
+ archiver->bba_ops->begin_file(archiver, relative_path, statbuf);
+}
+
+/* Does this archiver need the contents of the files? */
+static inline bool
+bbarchiver_needs_file_contents(bbarchiver *archiver)
+{
+ return archiver->bba_ops->file_contents != NULL;
+}
+
+/*
+ * Process contents of a plain file.
+ *
+ * Don't call this unless bbarchiver_needs_file_contents returns true.
+ */
+static inline void
+bbarchiver_file_contents(bbarchiver *archiver, const char *data, size_t len)
+{
+ Assert(archiver->bba_ops->file_contents != NULL);
+ archiver->bba_ops->file_contents(archiver, data, len);
+}
+
+/* Finish visiting a plain file. */
+static inline void
+bbarchiver_end_file(bbarchiver *archiver)
+{
+ Assert(archiver->bba_ops->end_file != NULL);
+ archiver->bba_ops->end_file(archiver);
+}
+
+/* Visit a directory. */
+static inline void
+bbarchiver_directory(bbarchiver *archiver, const char *relative_path,
+ struct stat *statbuf)
+{
+ Assert(archiver->bba_ops->directory != NULL);
+ archiver->bba_ops->directory(archiver, relative_path, statbuf);
+}
+
+/* Visit a symbolic link. */
+static inline void
+bbarchiver_symbolic_link(bbarchiver *archiver, const char *relative_path,
+ const char *linktarget, struct stat *statbuf)
+{
+ Assert(archiver->bba_ops->symbolic_link != NULL);
+ archiver->bba_ops->symbolic_link(archiver, relative_path, linktarget, statbuf);
+}
+
+/* Constructors for various types of archivers. */
+extern bbarchiver *bbarchiver_tar_new(bbsink *sink);
+extern bbarchiver *bbarchiver_tarsize_new(void);
+
+#endif
--
2.24.3 (Apple Git-128)