From 7d67ec8aebd18ba5000e17650c8f4dba1e8d11a2 Mon Sep 17 00:00:00 2001
From: Vladimir Davydov <vdavydov.dev@gmail.com>
Date: Tue, 18 Jul 2017 19:02:01 +0300
Subject: [PATCH] box: generate LSNs for rows received during initial join

Currently, 0 is passed to Index::commitCreate as index LSN during
initial join. To stop using index_opts->lsn for identifying indexes in
Vinyl, we need a unique LSN. So let's install a dummy journal to assign
fake unique LSNs for rows received on initial join.

Needed for #2536
---
 src/box/box.cc | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/box/box.cc b/src/box/box.cc
index e434a1ef9b..49360a22c8 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -268,7 +268,7 @@ struct recovery_journal {
  * exact same signature during local recovery to properly mark
  * min/max LSN of created LSM levels.
  */
-int64_t
+static int64_t
 recovery_journal_write(struct journal *base,
 		       struct journal_entry * /* entry */)
 {
@@ -283,6 +283,30 @@ recovery_journal_create(struct recovery_journal *journal, struct vclock *v)
 	journal->vclock = v;
 }
 
+/**
+ * Dummy journal used to generate unique LSNs for rows received
+ * during initial join.
+ */
+struct join_journal {
+	struct journal base;
+	int64_t lsn;
+};
+
+static int64_t
+join_journal_write(struct journal *base,
+		   struct journal_entry * /* entry */)
+{
+	struct join_journal *journal = (struct join_journal *) base;
+	return ++journal->lsn;
+}
+
+static inline void
+join_journal_create(struct join_journal *journal)
+{
+	journal_create(&journal->base, join_journal_write, NULL);
+	journal->lsn = 0;
+}
+
 static inline void
 apply_row(struct xstream *stream, struct xrow_header *row)
 {
@@ -1456,7 +1480,9 @@ bootstrap_from_master(struct replica *master)
 	 * Process initial data (snapshot or dirty disk data).
 	 */
 	engine_begin_initial_recovery(NULL);
-
+	struct join_journal join_journal;
+	join_journal_create(&join_journal);
+	journal_set(&join_journal.base);
 
 	applier_resume_to_state(applier, APPLIER_FINAL_JOIN, TIMEOUT_INFINITY);
 	/*
-- 
GitLab