changeset 431:1bb59652d89c

fixing merge...
author one
date Sun, 03 Jan 2010 01:01:52 +0900
parents 03ab374605a6
children 46199cf0046e
files Todo rep/handler/Editor.java rep/handler/Forwarder.java rep/handler/REPNode.java rep/handler/Translator.java test/mergertest/EditorSimulatorImpl.java test/mergertest/TestMerger.java test/sematest/TestEditor.java test/sematest/TestInterManagerSession.java test/sematest/TestSessionManager.java
diffstat 10 files changed, 119 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Sat Jan 02 04:16:25 2010 +0900
+++ b/Todo	Sun Jan 03 01:01:52 2010 +0900
@@ -1,3 +1,33 @@
+Sat Jan  2 20:52:17 JST 2010
+
+uMergeList のDELETE command のdeleted text が正しくない...
+なので、最初の一回は良いのだが二回目ででたらめになってしまう。
+これは、考えてなかった。
+  Translator.checkMergeConflict 
+が受け取っているので、それを uMergeList にすれば良いのだが...
+
+ちょっと、やっかいなプログラムになるかも。
+
+    unMergeList はMerge 後、削除  ( まだ merge してない list )
+    sentList はいじれない         ( 自分が他のエディタに送信した list)
+
+    sentMergeList                 ( 送信した merge command )
+    mergeAgainList                ( merge 中に自分のeditorに割り込まれた分 )
+
+確かに、mergeAgainList とかなんか、quueue が多すぎ。
+
+
+sort なんだけど...
+
+    e0 e1 e2 e0 e1 e2 e0 e1 e2 e0 e1 e2 e0
+     |-------|--------|--------|
+        |--------|--------|--------|
+           |--------|--------|--------|
+
+となる。なので、単純な editor id の順序では、まずいのでは?
+(自分の以外はack) ack の eid からの剰余で廻せば良いはず。
+
+
 Sat Jan  2 03:27:47 JST 2010
 
 うーん、まだ、だめですね。
@@ -9,6 +39,8 @@
 
 Todo:
     writeLog に level/flag を付けるか?
+Done:
+    既に付いてました。
 
 Selector.select() のフラグは意味がない。その後、必ず、
 selectedKeys() を調べる必要がある。これは、Simulator
--- a/rep/handler/Editor.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/rep/handler/Editor.java	Sun Jan 03 01:01:52 2010 +0900
@@ -120,10 +120,7 @@
 			//他のエディタからの編集コマンド
 			if (waitingRequired(command)) return;
 			translator.transReceiveCmd(next,command);
-			if(command.cmd==REP.REPCMD_DELETE) {
-				// delete のundo用の文字列は、外に出す意味はない
-				command.string=null;
-			}
+
 			sendEditorCommand(command);
 			return;
 		default:
@@ -183,18 +180,33 @@
 		}
 		waitingCommandInMerge.add(set);
 	}
-	
+
+	/**
+	 * 他のエディタへのコマンドの送信
+	 * @param command
+	 * 
+	 * sendList にキープする必要がある。 
+	 */
 	private void sendEditorCommand(REPCommand command) {
 		REPCommand keep = new REPCommand(command);
 		sentList.add(keep);
 		//ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
 		assert(sentList.size()<limit);
+		if (command.cmd==REP.REPCMD_DELETE) {
+			// delete のundo用の文字列は、外に出す意味はない
+			command.string=null;
+		}
 		next.send(command);
 	}
 
 	boolean merge(REPCommand command) {
 		//マージして送信
-		return translator.catchOwnCommand(this);
+		return translator.catchOwnCommand(this, command.eid);
+	}
+
+	@Override
+	public  List<REPCommand> getSentList() {
+		return sentList;
 	}
 
 	/**
--- a/rep/handler/Forwarder.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/rep/handler/Forwarder.java	Sun Jan 03 01:01:52 2010 +0900
@@ -1,6 +1,7 @@
 package rep.handler;
 
 import java.io.IOException;
+import java.util.List;
 
 import rep.PacketSet;
 import rep.REP;
@@ -145,6 +146,11 @@
 		
 	}
 
+	@Override
+	public List<REPCommand> getSentList() {
+		return null;
+	}
+
 	
 	
 	
--- a/rep/handler/REPNode.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/rep/handler/REPNode.java	Sun Jan 03 01:01:52 2010 +0900
@@ -1,6 +1,7 @@
 package rep.handler;
 
 import java.io.IOException;
+import java.util.List;
 
 import rep.REP;
 import rep.REPCommand;
@@ -159,6 +160,9 @@
 	public abstract void forwardedCommandManage(REPCommand command) ;
 
 	public abstract void checkWaitingCommandInMerge();
+
+	public abstract List<REPCommand> getSentList() ;
+
 		
 	
 	
--- a/rep/handler/Translator.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/rep/handler/Translator.java	Sun Jan 03 01:01:52 2010 +0900
@@ -17,7 +17,7 @@
 	public REPCommandOptimizer optimizer;
 	private LinkedList<REPCommand> unMergedCmds;
 	public LinkedList<REPCommand> sentMergedList;
-	private LinkedList<REPCommand> mergeAgainList;
+	boolean mergeAgain;
 	public REPLogger logger = SessionManager.logger;
 	boolean merge_mode = false;
 
@@ -25,7 +25,7 @@
 		eid = _eid;
 		optimizer = opt;
 		unMergedCmds = new LinkedList<REPCommand>();
-		mergeAgainList = new LinkedList<REPCommand>();
+		mergeAgain = false;
 		sentMergedList = new LinkedList<REPCommand>();
 	}
 
@@ -37,15 +37,16 @@
 	 */
 	public REPCommand transSendCmd(REPCommand cmd){
 		assert(cmd.eid==eid);
-		unMergedCmds.add(cmd);
+		unMergedCmds.addLast(cmd);
 		
 		//マージ中にユーザから割り込みがあった場合
 		if(isMerging()){
-			mergeAgainList.add(cmd);
+			mergeAgain = true;
 		}
 		
 		return cmd;
 	}
+	
 	/**
 	 * My command is returned from the session ring, and START_MERGE_ACK
 	 * is returned. At this
@@ -53,21 +54,25 @@
 	 * Start merge process.
 	 * @param cmd
 	 */
-	public boolean catchOwnCommand(REPNode editor){
+	public boolean catchOwnCommand(REPNode editor, int eid){
 		logger.writeLog("beforeMerge:"+unMergedCmds);
 		LinkedList<REPCommand> output = new LinkedList<REPCommand>();
-		TreeSet<REPCommand> cmds = new TreeSet<REPCommand>(new REPCommandComparator());
+		TreeSet<REPCommand> cmds = new TreeSet<REPCommand>(new REPCommandComparator(eid));
 		// merge queue上にあるコマンドを全部undoコマンドするのと同時に
 		// sort したコマンド列を生成する
 		for( REPCommand cmd0 : unMergedCmds) {
 			output.add( createUndo(cmd0) );
+		}
+		for( REPCommand cmd0 : editor.getSentList()) {
 			cmds.add(cmd0);
 		}
 		output.addAll(cmds);
 		// ACKが来たものは必ず先頭
-		unMergedCmds.removeFirst();
+		
+		// unMerged command のdeleteのundo string は、この時点で使えない。
+		// Editor 側から送り返して来たものを使う必要がある。
+		unMergedCmds.clear();
 		logger.writeLog("outputMerge:"+output);
-		logger.writeLog("afterMerge:"+unMergedCmds);
 		return optimizedSend(editor,output);
 	}
 
@@ -102,10 +107,15 @@
 	}
 
 	class REPCommandComparator implements Comparator<REPCommand>{
-
+		int base;
+		REPCommandComparator(int base) {
+			this.base = base;
+		}
 		public int compare(REPCommand o1, REPCommand o2) {
-			if ( o1.eid<o2.eid ) return -1;
-			if ( o1.eid>o2.eid ) return 1;
+			int eid1 = o1.eid-base; if (eid1<0) eid1 += Integer.MAX_VALUE;
+			int eid2 = o2.eid-base; if (eid2<0) eid2 += Integer.MAX_VALUE;
+			if ( eid1<eid2 ) return -1;
+			if ( eid1>eid2 ) return 1;
 			if ( o1.seq<o2.seq ) return -1;
 			if ( o1.seq>o2.seq ) return 1;
 			assert(false);
@@ -120,7 +130,7 @@
 	 */
 	public void transReceiveCmd(REPNode nextEditor,REPCommand cmd){
 		assert (cmd.eid != eid);
-		unMergedCmds.add(cmd);
+		unMergedCmds.addLast(cmd);
 	}
 
 	public void setEid(int _eid){
@@ -128,11 +138,11 @@
 	}
 
 	public boolean checkMergeConflict(REPCommand command) {
+		unMergedCmds.addLast(command);
 		REPCommand prev = sentMergedList.remove();
-		assert (prev.seq==command.seq);
+		//assert (prev.seq==command.seq);
 		
-		if(mergeAgainList.size() > 0){
-			mergeAgainList.add(command);
+		if (mergeAgain) {
 			return true;
 		}
 		if(sentMergedList.size()==0) {
@@ -143,21 +153,25 @@
 
 	public void getMergeAgain(REPNode editor) {
 		LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>();
-		for(int i = 0; i < mergeAgainList.size(); i++){
-			//eid = REP.MEGE_EID
-			returnCommand.add(createUndo(mergeAgainList.get(mergeAgainList.size() - i -1)));
+		LinkedList<REPCommand> merge = new LinkedList<REPCommand>();
+		LinkedList<REPCommand> conflict = new LinkedList<REPCommand>();
+		for(REPCommand command : unMergedCmds) {
+			returnCommand.add(createUndo(command));
 		}
-		for(REPCommand command : mergeAgainList){
+		for(REPCommand command : unMergedCmds) {
 			if(command.eid == REP.MERGE_EID.id){
-				returnCommand.add(command);
+				merge.addLast(command);
 			}
 		}
-		for(REPCommand command : mergeAgainList){
+		for(REPCommand command : unMergedCmds){
 			if(command.eid == eid){
 				command.eid = REP.MERGE_EID.id;
-				returnCommand.add(command);
+				conflict.addLast(command);
 			}
 		}
+		unMergedCmds.clear();
+		returnCommand.addAll(merge);
+		returnCommand.addAll(conflict);
 //		int count = 0;
 //		for(REPCommand command: returnCommand) {
 //			switch(command.cmd) {
@@ -168,7 +182,7 @@
 //		}
 		logger.writeLog("MergeAgain ret="+returnCommand.size());
 //				+" increment="+count);
-		mergeAgainList.clear();
+		mergeAgain = false;
 		optimizedSend(editor, returnCommand);
 	}
 
@@ -183,7 +197,7 @@
 	}
 
 	public void startMerge(REPCommand cmd) {
-		logger.writeLog("START MERGE command ="+cmd+" and top of unMergedCmds = "+ unMergedCmds.getFirst());
+		logger.writeLog("START MERGE command ="+cmd+" and top of unMergedCmds = "+ unMergedCmds.getLast());
 		merge_mode = true;
 	}
 
--- a/test/mergertest/EditorSimulatorImpl.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/test/mergertest/EditorSimulatorImpl.java	Sun Jan 03 01:01:52 2010 +0900
@@ -1,5 +1,7 @@
 package test.mergertest;
 
+import java.util.List;
+
 import rep.REPCommand;
 import rep.handler.Translator;
 import rep.optimizers.NullOptimizer;
@@ -21,4 +23,9 @@
 		Logger.print(command);
 	}
 
+	@Override
+	public List<REPCommand> getSentList() {
+		return null;
+	}
+
 }
--- a/test/mergertest/TestMerger.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/test/mergertest/TestMerger.java	Sun Jan 03 01:01:52 2010 +0900
@@ -2,6 +2,7 @@
 
 import java.io.IOException;
 import java.util.LinkedList;
+import java.util.List;
 
 import rep.REP;
 import rep.REPCommand;
@@ -49,7 +50,7 @@
 			trans.transReceiveCmd(null, command);
 		}
 		for(int i = 0; i < commandList.size(); i++){
-			trans.catchOwnCommand(this);
+			trans.catchOwnCommand(this,eid);
 			System.out.println();
 		}
 	}
@@ -131,4 +132,10 @@
 		// TODO Auto-generated method stub
 		
 	}
+
+	@Override
+	public List<REPCommand> getSentList() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
--- a/test/sematest/TestEditor.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/test/sematest/TestEditor.java	Sun Jan 03 01:01:52 2010 +0900
@@ -262,13 +262,15 @@
 		case SMCMD_JOIN_ACK	:
 			sid = cmd.sid;
 			eid = cmd.eid;
-			name += "(eid="+eid+",sid="+sid+")";
+			setName(name+eid);
+			name += "(sid="+sid+")";
 			inputLock = false;
 			break;
 		case SMCMD_PUT_ACK	:
 			sid = cmd.sid;
 			eid = cmd.eid;
-			name += "(eid="+eid+",sid="+sid+")";
+			setName(name+eid);
+			name += "(sid="+sid+")";
 			inputLock = false;
 			break;
 		case SMCMD_QUIT		:
--- a/test/sematest/TestInterManagerSession.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/test/sematest/TestInterManagerSession.java	Sun Jan 03 01:01:52 2010 +0900
@@ -106,7 +106,7 @@
 			LinkedList<REPCommand>cmds = new LinkedList<REPCommand>();
 			cmds.add(new REPCommand(REP.SMCMD_JOIN,0,0,0,0,""));
 			//if (inscnt-->0) cmds.add(new REPCommand(REP.REPCMD_INSERT,0,0,0,0,"m0"));
-			editors[i] = new TestEditor("Editor"+i,host,port,master);
+			editors[i] = new TestEditor("Editor",host,port,master);
 			//editors[i].setCommand(cmds);
 		}
 		setupEditor0();
--- a/test/sematest/TestSessionManager.java	Sat Jan 02 04:16:25 2010 +0900
+++ b/test/sematest/TestSessionManager.java	Sun Jan 03 01:01:52 2010 +0900
@@ -67,7 +67,7 @@
 			int port = editorPort[i%editorPort.length];
 			boolean master = editorMaster[i%editorMaster.length];
 			// TestEditor extends Thread
-			editors[i] = new TestEditor("Editor"+i,host,port,master);
+			editors[i] = new TestEditor("Editor",host,port,master);
 		}
 	}