This is an automated email from the ASF dual-hosted git repository.

jiangtian pushed a commit to branch cluster_new
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/cluster_new by this push:
     new 3c4de8d  use binary search when check the matched index when snapshot
     new 8b75116  Merge pull request #1836 from 
neuyilan/apache_cluster_new_1020_binary_search_matchterm
3c4de8d is described below

commit 3c4de8d7fbe532141f2fc4319dfd6eaa09995211
Author: HouliangQi <[email protected]>
AuthorDate: Tue Oct 20 10:51:31 2020 +0800

    use binary search when check the matched index when snapshot
---
 .../iotdb/cluster/log/catchup/CatchUpTask.java     | 65 +++++++++++++--------
 .../iotdb/cluster/server/member/RaftMember.java    |  2 +-
 .../iotdb/cluster/log/catchup/CatchUpTaskTest.java | 67 +++++++++++++++++++++-
 .../java/org/apache/iotdb/db/metadata/MTree.java   |  1 -
 4 files changed, 106 insertions(+), 29 deletions(-)

diff --git 
a/cluster/src/main/java/org/apache/iotdb/cluster/log/catchup/CatchUpTask.java 
b/cluster/src/main/java/org/apache/iotdb/cluster/log/catchup/CatchUpTask.java
index 7758187..90d493f 100644
--- 
a/cluster/src/main/java/org/apache/iotdb/cluster/log/catchup/CatchUpTask.java
+++ 
b/cluster/src/main/java/org/apache/iotdb/cluster/log/catchup/CatchUpTask.java
@@ -36,6 +36,7 @@ import org.apache.iotdb.cluster.server.NodeCharacter;
 import org.apache.iotdb.cluster.server.Peer;
 import org.apache.iotdb.cluster.server.member.RaftMember;
 import org.apache.iotdb.cluster.utils.ClientUtils;
+import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -91,18 +92,40 @@ public class CatchUpTask implements Runnable {
       logger.error("Unexpected error in logManager's getEntries during 
matchIndexCheck", e);
     }
 
-    int index = logs.size() - 1;
-    // if index < 0 then send Snapshot and all the logs in logManager
-    // if index >= 0 but there is no matched log, still send Snapshot and all 
the logs in logManager
-    while (index >= 0) {
-      if (checkMatchIndex(index)) {
-        logger.info("{}: Find a match index {} of {}", raftMember.getName(), 
index, node);
-        return true;
+    int index = findLastMatchIndex(logs);
+    if (index == -1) {
+      logger.info("Cannot find matched of {} within [{}, {}]", node, lo, hi);
+      return false;
+    }
+
+    // if follower return RESPONSE.AGREE with this empty log, then start 
sending real logs from index.
+    logs.subList(0, index).clear();
+    if (logger.isDebugEnabled()) {
+      if (logs.isEmpty()) {
+        logger.debug("{}: {} has caught up by previous catch up", 
raftMember.getName(), node);
+      } else {
+        logger.debug("{}: makes {} catch up with {} and other {} logs", 
raftMember.getName(),
+            node, logs.get(0), logs.size());
+      }
+    }
+    return true;
+  }
+
+  public int findLastMatchIndex(List<Log> logs)
+      throws LeaderUnknownException, TException, InterruptedException {
+    int start = 0;
+    int end = logs.size() - 1;
+    int matchedIndex = -1;
+    while (start <= end) {
+      int mid = start + (end - start) / 2;
+      if (checkMatchIndex(mid)) {
+        start = mid + 1;
+        matchedIndex = mid;
+      } else {
+        end = mid - 1;
       }
-      index--;
     }
-    logger.info("Cannot find matched of {} within [{}, {}]", node, lo, hi);
-    return false;
+    return matchedIndex;
   }
 
   /**
@@ -115,7 +138,6 @@ public class CatchUpTask implements Runnable {
    */
   private boolean checkMatchIndex(int index)
       throws LeaderUnknownException, TException, InterruptedException {
-    boolean isLogDebug = logger.isDebugEnabled();
     Log log = logs.get(index);
     synchronized (raftMember.getTerm()) {
       // make sure this node is still a leader
@@ -136,20 +158,7 @@ public class CatchUpTask implements Runnable {
     raftMember.getLastCatchUpResponseTime().put(node, 
System.currentTimeMillis());
     logger.debug("{} check {}'s matchIndex {} with log [{}]", 
raftMember.getName(), node,
         matched ? "succeed" : "failed", log);
-    if (!matched) {
-      return false;
-    }
-    // if follower return RESPONSE.AGREE with this empty log, then start 
sending real logs from index.
-    logs.subList(0, index).clear();
-    if (isLogDebug) {
-      if (logs.isEmpty()) {
-        logger.debug("{}: {} has caught up by previous catch up", 
raftMember.getName(), node);
-      } else {
-        logger.debug("{}: makes {} catch up with {} and other {} logs", 
raftMember.getName(),
-            node, logs.get(0), logs.size());
-      }
-    }
-    return true;
+    return matched;
   }
 
   /**
@@ -211,6 +220,7 @@ public class CatchUpTask implements Runnable {
     }
   }
 
+  @Override
   public void run() {
     try {
       boolean findMatchedIndex = checkMatchIndex();
@@ -250,4 +260,9 @@ public class CatchUpTask implements Runnable {
     // the next catch up is enabled
     raftMember.getLastCatchUpResponseTime().remove(node);
   }
+
+  @TestOnly
+  public void setLogs(List<Log> logs) {
+    this.logs = logs;
+  }
 }
diff --git 
a/cluster/src/main/java/org/apache/iotdb/cluster/server/member/RaftMember.java 
b/cluster/src/main/java/org/apache/iotdb/cluster/server/member/RaftMember.java
index 14b1610..c56c1f6 100644
--- 
a/cluster/src/main/java/org/apache/iotdb/cluster/server/member/RaftMember.java
+++ 
b/cluster/src/main/java/org/apache/iotdb/cluster/server/member/RaftMember.java
@@ -232,7 +232,7 @@ public abstract class RaftMember {
    */
   private LogDispatcher logDispatcher;
 
-  public RaftMember() {
+  protected RaftMember() {
   }
 
   protected RaftMember(String name, AsyncClientPool asyncPool, SyncClientPool 
syncPool,
diff --git 
a/cluster/src/test/java/org/apache/iotdb/cluster/log/catchup/CatchUpTaskTest.java
 
b/cluster/src/test/java/org/apache/iotdb/cluster/log/catchup/CatchUpTaskTest.java
index 0df45ae..6620fb0 100644
--- 
a/cluster/src/test/java/org/apache/iotdb/cluster/log/catchup/CatchUpTaskTest.java
+++ 
b/cluster/src/test/java/org/apache/iotdb/cluster/log/catchup/CatchUpTaskTest.java
@@ -31,10 +31,10 @@ import org.apache.iotdb.cluster.common.TestMetaGroupMember;
 import org.apache.iotdb.cluster.common.TestSyncClient;
 import org.apache.iotdb.cluster.common.TestUtils;
 import org.apache.iotdb.cluster.config.ClusterDescriptor;
+import org.apache.iotdb.cluster.exception.LeaderUnknownException;
 import org.apache.iotdb.cluster.exception.LogExecutionException;
 import org.apache.iotdb.cluster.log.Log;
 import org.apache.iotdb.cluster.log.LogParser;
-import org.apache.iotdb.cluster.log.Snapshot;
 import org.apache.iotdb.cluster.log.logtypes.EmptyContentLog;
 import org.apache.iotdb.cluster.partition.PartitionTable;
 import org.apache.iotdb.cluster.partition.slot.SlotPartitionTable;
@@ -49,8 +49,10 @@ import org.apache.iotdb.cluster.server.Peer;
 import org.apache.iotdb.cluster.server.Response;
 import org.apache.iotdb.cluster.server.member.RaftMember;
 import org.apache.iotdb.db.service.IoTDB;
+import org.apache.thrift.TException;
 import org.apache.thrift.async.AsyncMethodCallback;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -265,7 +267,8 @@ public class CatchUpTaskTest {
       }
       sender.getLogManager().append(logList);
       sender.getLogManager().commitTo(9);
-      
sender.getLogManager().setMaxHaveAppliedCommitIndex(sender.getLogManager().getCommitLogIndex());
+      sender.getLogManager()
+          
.setMaxHaveAppliedCommitIndex(sender.getLogManager().getCommitLogIndex());
       Node receiver = new Node();
       sender.setCharacter(NodeCharacter.LEADER);
       Peer peer = new Peer(10);
@@ -329,4 +332,64 @@ public class CatchUpTaskTest {
     assertEquals(logList, receivedLogs.subList(1, receivedLogs.size()));
     assertEquals(9, leaderCommit);
   }
+
+  @Test
+  public void testFindLastMatchIndex() throws LogExecutionException {
+    List<Log> logList = new ArrayList<>();
+    int lastMatchedIndex = 6;
+    for (int i = 0; i < 10; i++) {
+      Log log = new EmptyContentLog();
+      log.setCurrLogIndex(i);
+      log.setCurrLogTerm(i);
+      logList.add(log);
+
+      if (i < lastMatchedIndex) {
+        receivedLogs.add(log);
+      }
+    }
+    sender.getLogManager().append(logList);
+    sender.getLogManager().commitTo(9);
+    sender.getLogManager()
+        
.setMaxHaveAppliedCommitIndex(sender.getLogManager().getCommitLogIndex());
+    Node receiver = new Node();
+    sender.setCharacter(NodeCharacter.LEADER);
+    Peer peer = new Peer(10);
+    peer.setCatchUp(false);
+    peer.setMatchIndex(0);
+    peer.setNextIndex(0);
+
+    CatchUpTask task = new CatchUpTask(receiver, peer, sender);
+    task.setLogs(logList);
+    try {
+      // 1. case 1: the matched index is in the middle of the logs interval
+      int resultMatchIndex = task.findLastMatchIndex(logList);
+      assertEquals(lastMatchedIndex, resultMatchIndex);
+
+      // 2. case 2: no matched index case
+      lastMatchedIndex = -1;
+      receivedLogs.subList(1, receivedLogs.size()).clear();
+      resultMatchIndex = task.findLastMatchIndex(logList);
+      assertEquals(lastMatchedIndex, resultMatchIndex);
+
+      // 3. case 3: the matched index is at the last index of the logs
+      logList.clear();
+      receivedLogs.subList(1, receivedLogs.size()).clear();
+      lastMatchedIndex = 9;
+      for (int i = 0; i < 10; i++) {
+        Log log = new EmptyContentLog();
+        log.setCurrLogIndex(i);
+        log.setCurrLogTerm(i);
+        logList.add(log);
+
+        if (i < lastMatchedIndex) {
+          receivedLogs.add(log);
+        }
+      }
+      resultMatchIndex = task.findLastMatchIndex(logList);
+      assertEquals(lastMatchedIndex, resultMatchIndex);
+
+    } catch (LeaderUnknownException | TException | InterruptedException e) {
+      Assert.fail(e.getMessage());
+    }
+  }
 }
\ No newline at end of file
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index 5eed13b..8330f79 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -36,7 +36,6 @@ import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Deque;

Reply via email to