agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Kyotaro Horiguchi <[email protected]>
Subject: [PATCH 01/10] Define macros to make XLogReadRecord a state machine
Date: Thu, 18 Apr 2019 10:22:49 +0900
To minimize apparent imapct on code, use some macros as syntax sugar. This is a similar stuff with ExecInterpExpr but a bit different. The most significant difference is that this stuff allows some functions are leaved midst of their work then continue. Roughly speaking this is used as the follows.
enum retval
some_func()
{
static .. internal_variables;
XLR_SWITCH();
...
XLR_LEAVE(STATUS1, RETVAL_CONTINUE);
...
XLR_LEAVE(STATUS2, RETVAL_CONTINUE2);
...
XLR_SWITCH_END();
XLR_RETURN(RETVAL_FINISH);
}
The caller uses the function as follows:
while (some_func() != RETVAL_FINISH)
{
<do some work>;
}
---
src/backend/access/transam/xlogreader.c | 63 +++++++++++++++++++++++++++++++++
src/include/access/xlogreader.h | 3 ++
2 files changed, 66 insertions(+)
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 9196aa3aae..5299765040 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -29,6 +29,69 @@
#include "utils/memutils.h"
#endif
+/*
+ * Use computed-goto-based opcode dispatch when computed gotos are available.
+ * But use a separate symbol so that it's easy to adjust locally in this file
+ * for development and testing.
+ */
+#ifdef HAVE_COMPUTED_GOTO
+#define XLR_USE_COMPUTED_GOTO
+#endif /* HAVE_COMPUTED_GOTO */
+
+/*
+ * Macros for opcode dispatch.
+ *
+ * XLR_SWITCH - just hides the switch if not in use.
+ * XLR_CASE - labels the implementation of named expression step type.
+ * XLR_DISPATCH - jump to the implementation of the step type for 'op'.
+ * XLR_LEAVE - leave the function and return here at the next call.
+ * XLR_RETURN - return from the function and set state to initial state.
+ * XLR_END - just hides the closing brace if not in use.
+ */
+#if defined(XLR_USE_COMPUTED_GOTO)
+#define XLR_SWITCH() \
+ /* Don't call duplicatedly */ \
+ static int callcnt = 0 PG_USED_FOR_ASSERTS_ONLY; \
+ do { \
+ if ((XLR_STATE).j) \
+ goto *((void *) (XLR_STATE).j); \
+ XLR_CASE(XLR_INIT_STATE); \
+ Assert(++callcnt == 1); \
+ } while (0)
+#define XLR_CASE(name) name:
+#define XLR_DISPATCH() goto *((void *) (XLR_STATE).j)
+#define XLR_LEAVE(name, code) do { \
+ (XLR_STATE).j = (&&name); return (code); \
+ XLR_CASE(name); \
+ } while (0)
+#define XLR_RETURN(code) \
+ do { \
+ Assert(--callcnt == 0); \
+ (XLR_STATE).j = (&&XLR_INIT_STATE); return (code); \
+ } while (0)
+#define XLR_SWITCH_END()
+#else /* !XLR_USE_COMPUTED_GOTO */
+#define XLR_SWITCH() \
+ /* Don't call duplicatedly */ \
+ static int callcnt = 0 PG_USED_FOR_ASSERTS_ONLY; \
+ switch ((XLR_STATE).c) { \
+ XLR_CASE(XLR_INIT_STATE); \
+ Assert(++callcnt == 1); \
+#define XLR_CASE(name) case name:
+#define XLR_DISPATCH() goto starteval
+#define XLR_LEAVE(name, code) \
+ do { \
+ (XLR_STATE).c = (name); return (code); \
+ XLR_CASE(name); \
+ } while (0)
+#define XLR_RETURN(code) \
+ do { \
+ Assert(--callcnt == 0); \
+ (XLR_STATE).c = (XLR_INIT_STATE); return (code); \
+ } while (0)
+#define XLR_SWITCH_END() }
+#endif /* XLR_USE_COMPUTED_GOTO */
+
static bool allocate_recordbuf(XLogReaderState *state, uint32 reclength);
static bool ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr,
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index f3bae0bf49..30500c35c7 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -240,6 +240,9 @@ extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record,
#define XLogRecBlockImageApply(decoder, block_id) \
((decoder)->blocks[block_id].apply_image)
+/* Reset the reader state */
+#define XLREAD_RESET(state) ((state)->xlnd_state.j = (state)->xlread_state.j = 0)
+
extern bool RestoreBlockImage(XLogReaderState *recoder, uint8 block_id, char *dst);
extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len);
extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id,
--
2.16.3
----Next_Part(Thu_Apr_18_21_02_57_2019_406)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="0002-Make-ReadPageInternal-a-state-machine.patch"
view thread (10+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH 01/10] Define macros to make XLogReadRecord a state machine
In-Reply-To: <no-message-id-1883257@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox