[tarantool-patches] [PATCH] xlog: get rid of xlog_meta::has_prev_vclock

  • From: Vladimir Davydov <vdavydov.dev@xxxxxxxxx>
  • To: kostja@xxxxxxxxxxxxx
  • Date: Tue, 10 Jul 2018 19:28:24 +0300

Introduce vclock_is_set() helper and use it on xlog_meta::prev_vclock
instead.

Follow-up ac90b498d1b0 ("xlog: store prev vclock in xlog header").
---
https://github.com/tarantool/tarantool/commits/dv/wal-make-new-xlog-on-shutdown-follow-up

 src/box/recovery.cc |  2 +-
 src/box/vclock.h    | 21 +++++++++++++++
 src/box/vy_run.c    | 14 +++++-----
 src/box/xlog.c      | 78 +++++++++++++++++++++++++++++++----------------------
 src/box/xlog.h      | 14 ++++++++--
 5 files changed, 86 insertions(+), 43 deletions(-)

diff --git a/src/box/recovery.cc b/src/box/recovery.cc
index 2cab8308..f0b85a53 100644
--- a/src/box/recovery.cc
+++ b/src/box/recovery.cc
@@ -154,7 +154,7 @@ recovery_open_log(struct recovery *r, const struct vclock 
*vclock)
        }
 
        if (state != XLOG_CURSOR_NEW &&
-           r->cursor.meta.has_prev_vclock &&
+           vclock_is_set(&r->cursor.meta.prev_vclock) &&
            vclock_compare(&r->cursor.meta.prev_vclock, &meta.vclock) != 0) {
                /*
                 * WALs are missing between the last scanned WAL
diff --git a/src/box/vclock.h b/src/box/vclock.h
index 3cd60102..be835360 100644
--- a/src/box/vclock.h
+++ b/src/box/vclock.h
@@ -118,6 +118,27 @@ vclock_create(struct vclock *vclock)
        memset(vclock, 0, sizeof(*vclock));
 }
 
+/**
+ * Reset a vclock object. After this function is called,
+ * vclock_is_set() will return false.
+ */
+static inline void
+vclock_clear(struct vclock *vclock)
+{
+       memset(vclock, 0, sizeof(*vclock));
+       vclock->signature = -1;
+}
+
+/**
+ * Returns false if the vclock was cleared with vclock_clear(),
+ * true otherwise.
+ */
+static inline bool
+vclock_is_set(const struct vclock *vclock)
+{
+       return vclock->signature >= 0;
+}
+
 static inline int64_t
 vclock_get(const struct vclock *vclock, uint32_t replica_id)
 {
diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index dc837c2b..eae3e74d 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -1960,10 +1960,9 @@ vy_run_write_index(struct vy_run *run, const char 
*dirpath,
        say_info("writing `%s'", path);
 
        struct xlog index_xlog;
-       struct xlog_meta meta = {
-               .filetype = XLOG_META_TYPE_INDEX,
-               .instance_uuid = INSTANCE_UUID,
-       };
+       struct xlog_meta meta;
+       xlog_meta_create(&meta, XLOG_META_TYPE_INDEX, &INSTANCE_UUID,
+                        NULL, NULL);
        if (xlog_create(&index_xlog, path, 0, &meta) < 0)
                return -1;
 
@@ -2057,10 +2056,9 @@ vy_run_writer_create_xlog(struct vy_run_writer *writer)
                            writer->space_id, writer->iid, writer->run->id,
                            VY_FILE_RUN);
        say_info("writing `%s'", path);
-       const struct xlog_meta meta = {
-               .filetype = XLOG_META_TYPE_RUN,
-               .instance_uuid = INSTANCE_UUID,
-       };
+       struct xlog_meta meta;
+       xlog_meta_create(&meta, XLOG_META_TYPE_RUN, &INSTANCE_UUID,
+                        NULL, NULL);
        if (xlog_create(&writer->data_xlog, path, 0, &meta) != 0)
                return -1;
        writer->data_xlog.rate_limit = writer->run->env->snap_io_rate_limit;
diff --git a/src/box/xlog.c b/src/box/xlog.c
index 59459b25..5ed11fc8 100644
--- a/src/box/xlog.c
+++ b/src/box/xlog.c
@@ -98,6 +98,24 @@ enum {
 static const char v13[] = "0.13";
 static const char v12[] = "0.12";
 
+void
+xlog_meta_create(struct xlog_meta *meta, const char *filetype,
+                const struct tt_uuid *instance_uuid,
+                const struct vclock *vclock,
+                const struct vclock *prev_vclock)
+{
+       snprintf(meta->filetype, sizeof(meta->filetype), "%s", filetype);
+       meta->instance_uuid = *instance_uuid;
+       if (vclock != NULL)
+               vclock_copy(&meta->vclock, vclock);
+       else
+               vclock_clear(&meta->vclock);
+       if (prev_vclock != NULL)
+               vclock_copy(&meta->prev_vclock, prev_vclock);
+       else
+               vclock_clear(&meta->prev_vclock);
+}
+
 /**
  * Format xlog metadata into @a buf of size @a size
  *
@@ -113,21 +131,26 @@ static const char v12[] = "0.12";
 static int
 xlog_meta_format(const struct xlog_meta *meta, char *buf, int size)
 {
-       char *vstr = vclock_to_string(&meta->vclock);
-       if (vstr == NULL)
-               return -1;
-       char *instance_uuid = tt_uuid_str(&meta->instance_uuid);
        int total = 0;
        SNPRINT(total, snprintf, buf, size,
                "%s\n"
                "%s\n"
                VERSION_KEY ": %s\n"
-               INSTANCE_UUID_KEY ": %s\n"
-               VCLOCK_KEY ": %s\n",
-               meta->filetype, v13, PACKAGE_VERSION, instance_uuid, vstr);
-       free(vstr);
-       if (meta->has_prev_vclock) {
-               vstr = vclock_to_string(&meta->prev_vclock);
+               INSTANCE_UUID_KEY ": %s\n",
+               meta->filetype, v13, PACKAGE_VERSION,
+               tt_uuid_str(&meta->instance_uuid));
+       if (vclock_is_set(&meta->vclock)) {
+               char *vstr = vclock_to_string(&meta->vclock);
+               if (vstr == NULL)
+                       return -1;
+               SNPRINT(total, snprintf, buf, size,
+                       VCLOCK_KEY ": %s\n", vstr);
+               free(vstr);
+       }
+       if (vclock_is_set(&meta->prev_vclock)) {
+               char *vstr = vclock_to_string(&meta->prev_vclock);
+               if (vstr == NULL)
+                       return -1;
                SNPRINT(total, snprintf, buf, size,
                        PREV_VCLOCK_KEY ": %s\n", vstr);
                free(vstr);
@@ -214,6 +237,9 @@ xlog_meta_parse(struct xlog_meta *meta, const char **data,
                return -1;
        }
 
+       vclock_clear(&meta->vclock);
+       vclock_clear(&meta->prev_vclock);
+
        /*
         * Parse "key: value" pairs
         */
@@ -263,7 +289,6 @@ xlog_meta_parse(struct xlog_meta *meta, const char **data,
                         */
                        if (parse_vclock(val, val_end, &meta->prev_vclock) != 0)
                                return -1;
-                       meta->has_prev_vclock = true;
                } else if (memcmp(key, VERSION_KEY, key_end - key) == 0) {
                        /* Ignore Version: for now */
                } else {
@@ -748,7 +773,8 @@ xlog_create(struct xlog *xlog, const char *name, int flags,
        int meta_len;
 
        /*
-        * Check that the file without .inprogress suffix doesn't exist.
+        * Check whether a file with this name already exists.
+        * We don't overwrite existing files.
         */
        if (access(name, F_OK) == 0) {
                errno = EEXIST;
@@ -905,35 +931,23 @@ int
 xdir_create_xlog(struct xdir *dir, struct xlog *xlog,
                 const struct vclock *vclock)
 {
-       char *filename;
        int64_t signature = vclock_sum(vclock);
-       struct xlog_meta meta;
        assert(signature >= 0);
        assert(!tt_uuid_is_nil(dir->instance_uuid));
 
        /*
-       * Check whether a file with this name already exists.
-       * We don't overwrite existing files.
-       */
-       filename = xdir_format_filename(dir, signature, NONE);
-
-       /* Setup inherited values */
-       snprintf(meta.filetype, sizeof(meta.filetype), "%s", dir->filetype);
-       meta.instance_uuid = *dir->instance_uuid;
-       vclock_copy(&meta.vclock, vclock);
-
-       /*
         * For WAL dir: store vclock of the previous xlog file
         * to check for gaps on recovery.
         */
-       if (dir->type == XLOG && !vclockset_empty(&dir->index)) {
-               vclock_copy(&meta.prev_vclock, vclockset_last(&dir->index));
-               meta.has_prev_vclock = true;
-       } else {
-               vclock_create(&meta.prev_vclock);
-               meta.has_prev_vclock = false;
-       }
+       const struct vclock *prev_vclock = NULL;
+       if (dir->type == XLOG && !vclockset_empty(&dir->index))
+               prev_vclock = vclockset_last(&dir->index);
+
+       struct xlog_meta meta;
+       xlog_meta_create(&meta, dir->filetype, dir->instance_uuid,
+                        vclock, prev_vclock);
 
+       char *filename = xdir_format_filename(dir, signature, NONE);
        if (xlog_create(xlog, filename, dir->open_wflags, &meta) != 0)
                return -1;
 
diff --git a/src/box/xlog.h b/src/box/xlog.h
index d27e38e6..476105c2 100644
--- a/src/box/xlog.h
+++ b/src/box/xlog.h
@@ -246,10 +246,20 @@ struct xlog_meta {
         * directory for missing WALs.
         */
        struct vclock prev_vclock;
-       /** Set if @prev_vclock is present. */
-       bool has_prev_vclock;
 };
 
+/**
+ * Initialize xlog meta struct.
+ *
+ * @vclock and @prev_vclock are optional: if the value is NULL,
+ * the key won't be written to the xlog header.
+ */
+void
+xlog_meta_create(struct xlog_meta *meta, const char *filetype,
+                const struct tt_uuid *instance_uuid,
+                const struct vclock *vclock,
+                const struct vclock *prev_vclock);
+
 /* }}} */
 
 /**
-- 
2.11.0


Other related posts:

  • » [tarantool-patches] [PATCH] xlog: get rid of xlog_meta::has_prev_vclock - Vladimir Davydov