changeset 449:89a326696c54

mergeMark in sentList
author one
date Wed, 22 Sep 2010 22:11:58 +0900
parents ed97273477a0
children 21cb16b7f3df
files Todo rep/handler/Editor.java rep/handler/Translator.java
diffstat 3 files changed, 48 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Wed Sep 22 17:42:47 2010 +0900
+++ b/Todo	Wed Sep 22 22:11:58 2010 +0900
@@ -1,3 +1,30 @@
+Wed Sep 22 19:59:26 JST 2010
+
+NOPを廻す方式とAckを廻す方式は、
+
+    E_{10} N_{11} E_{23} E_{01} E_{02} N_{11}
+
+    E_{10}        E_{23} E_{01} E_{02} Eack_{10}
+
+の対応だから、方法としては同じ。 
+
+sort だけど、
+
+    e3 e1 e2 e3 e1 e2 e3 e1 e2 e3 e1 e2 e3
+     |---1---|----4---|--------|
+        |----2---|--------|--------|
+           |----3---|--------|--------|
+
+1 では c1 のack で c1 c2 c3 の順序にmerge。c1 c2 c3 は確定。
+なので、2,3 ではソートは必要ない? じゃぁ、Self merge だけ
+すれば良いってこと? じゃぁ、その他の Ack の意味は?
+さすがにそれはないです。
+
+sort するリスト は、merge の時にclearして良いらしい。
+と言うことは unMerge もclearして良い。
+sentList にMarkを入れるか。
+
+
 Fri Sep 17 16:31:04 JST 2010
 
 あぁ、そうか。二つ続けてeditor commandを送ると、二つ続けて Merge することに
--- a/rep/handler/Editor.java	Wed Sep 22 17:42:47 2010 +0900
+++ b/rep/handler/Editor.java	Wed Sep 22 22:11:58 2010 +0900
@@ -22,6 +22,7 @@
 	private REPCommand quit2=null;
 	private REPCommand preMergeCommand;
 	private boolean merging;
+	private REPCommand mergeMark = new REPCommand(REP.SMCMD_START_MERGE, 0,0, 0, 0, "");
 	public static boolean noMergeMode=false;
 	static final boolean doOptimize = false;
 
@@ -33,6 +34,7 @@
 	public Editor(int editorNo, SessionManager manager,REPSocketChannel<REPCommand> channel){
 		super(editorNo,manager,channel);
 		eid = editorNo;
+		sentList.add(mergeMark);  // merge mark
 		REPCommandOptimizer optimizer;
 		if (doOptimize) optimizer = new DeleteInsertOptimizer(); //タカノがつくったおぷてぃまいざ
 		else            optimizer = new NullOptimizer();         //なにもしないけどOptimizer.
@@ -85,9 +87,9 @@
 		case REPCMD_INSERT_ACK:
 		case REPCMD_DELETE_ACK:
 			if (waitingRequired(command,null)) return;
+			checkAck(command);
 			if (command.eid==eid) {
 				// Second Phase が終わって同期が終了。
-				checkAck(command);
 				// SessionManager.logger.writeLog("Complete "+command);
 				checkQuit();
 				return;
@@ -230,8 +232,10 @@
 
 	private boolean checkAck(REPCommand command) {
 		assert(!merging);
-		REPCommand prev = sentList.pollFirst();
+		REPCommand prev;
+		if (sentList.getFirst()==mergeMark) prev=sentList.remove(1); else prev=sentList.remove(0);		
 		if (prev==null || prev.seq != command.seq || prev.eid!=command.eid) {
+			// should be more robust to allow communication failure
 			String err = "Editor eid="+eid+" checkReturnedCommand() : command = " + command + " prev="+
 				(prev==null?"null":prev)+" sentList=";
 			err += sentList;
@@ -298,8 +302,9 @@
 		translator.endMerge();
 		REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,"");
 		send(mergeEnd);
-		sentList.remove(0);
 		if (preMergeCommand.eid==eid) {
+			// Ackの場合はcheckAck() で既にremoveされている
+			if (sentList.getFirst()==mergeMark) sentList.remove(1); else sentList.remove(0);		
 			// First Phase End, send ACK
 			REPCommand keep = new REPCommand(preMergeCommand);
 			switch(keep.cmd) {
@@ -307,18 +312,20 @@
 			case REPCMD_DELETE: keep.cmd = REP.REPCMD_DELETE_ACK;break;
 			default: assert(false);
 			}
-			sentList.add(preMergeCommand);
+			sentList.addLast(preMergeCommand);
 			//ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
 			assert(sentList.size()<limit);
 			next.send(keep);
 		} else {
 			next.send(preMergeCommand);
 		}
+		sentList.remove(mergeMark);
+		sentList.addLast(mergeMark);
 		preMergeCommand = null;
 	}
 
 	private boolean checkQuit() {
-		if (quit2!=null && sentList.size()==0&&!isMerging()) {
+		if (quit2!=null && sentList.size()==1&&!isMerging()) {
 			send(quit2);
 			quit2 = null;
 			return true;
--- a/rep/handler/Translator.java	Wed Sep 22 17:42:47 2010 +0900
+++ b/rep/handler/Translator.java	Wed Sep 22 22:11:58 2010 +0900
@@ -66,7 +66,13 @@
 
 		sortedEditCmds = new TreeSet<REPCommand>(new REPCommandComparator(1));
 		logger.writeLog("sentList"+eid+":"+editor.getSentList());
+		boolean merged = true;
 		for( REPCommand cmd0 : editor.getSentList()) {
+			if (cmd0.cmd==REP.SMCMD_START_MERGE) {
+				merged = false;
+				continue;
+			}
+			if (merged) continue;
 			if (cmd0.cmd==REP.REPCMD_INSERT || cmd0.cmd==REP.REPCMD_DELETE)
 				sortedEditCmds.add(cmd0);
 		}
@@ -86,12 +92,8 @@
 	 * Received all merge command ack
 	 */
 	public void endMerge() {
-		LinkedList<REPCommand> n = new LinkedList<REPCommand>();
-		for(int i=0;i< sortedEditCmds.size()-1;i++) {
-			n.addLast(unMergedCmds.get(i));
-		}
 		sortedEditCmds = null;
-		unMergedCmds = n;
+		unMergedCmds = new LinkedList<REPCommand>();
 	}
 	/**
 	 * Sent optimized merged command list
@@ -218,7 +220,8 @@
 	}
 
 	public void startMerge(REPCommand cmd) {
-		logger.writeLog("START MERGE command ="+cmd+" and top of unMergedCmds = "+ unMergedCmds.getLast());
+		logger.writeLog("START MERGE command ="+cmd+
+				((unMergedCmds.size()>0)?" and top of unMergedCmds = "+ unMergedCmds.getLast():""));
 		merge_mode = true;
 	}