changeset 400:29f01a7ce71f

INSERT_USER,DELETE_USER to distinguish user input
author one
date Tue, 25 Nov 2008 01:41:11 +0900
parents 19705f4b8015
children 2cf5392b2a9f
files Todo rep/PacketSet.java rep/REP.java rep/handler/Editor.java test/Text.java test/sematest/TestEditor.java
diffstat 6 files changed, 89 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Mon Nov 24 23:11:51 2008 +0900
+++ b/Todo	Tue Nov 25 01:41:11 2008 +0900
@@ -3,6 +3,10 @@
 watingCommandInMerge のqueueを一旦0にしてから、manageを
 呼ぶと、queueが既にあるのに、lockが外れた状態になってしまう。
 
+watingCommandInMerge にforwardedCommandManageから入れちゃうと、
+User Editor Command と 一周して来てからのCommandを区別できない...
+
+
 Wed Nov 19 19:21:47 JST 2008
 
 ACK base に書き換えるのは良いが、途中でjoinして
--- a/rep/PacketSet.java	Mon Nov 24 23:11:51 2008 +0900
+++ b/rep/PacketSet.java	Tue Nov 25 01:41:11 2008 +0900
@@ -19,5 +19,8 @@
 		return editor;
 	}
 	
+	public String toString() {
+		return "PacketSet("+command.toString()+","+editor+")";
+	}
 
 }
--- a/rep/REP.java	Mon Nov 24 23:11:51 2008 +0900
+++ b/rep/REP.java	Tue Nov 25 01:41:11 2008 +0900
@@ -1,8 +1,10 @@
 package rep;
 
 public enum REP {
+	 REPCMD_INSERT_USER	( 5),
 	 REPCMD_INSERT	( 6),
 	 REPCMD_INSERT_ACK	( 7),
+	 REPCMD_DELETE_USER	( 8),
 	 REPCMD_DELETE	( 9),
 	 REPCMD_DELETE_ACK	( 10),
 	 REPCMD_CLOSE	( 11),
--- a/rep/handler/Editor.java	Mon Nov 24 23:11:51 2008 +0900
+++ b/rep/handler/Editor.java	Tue Nov 25 01:41:11 2008 +0900
@@ -51,45 +51,58 @@
 			if (waitingRequired(command)) return;
 			checkReturnedCommand(command);
 			return;
+		case REPCMD_INSERT_USER:
+			command.cmd = REP.REPCMD_INSERT;
+			userEditorCommand(command);
+			return;
+		case REPCMD_DELETE_USER:
+			command.cmd = REP.REPCMD_INSERT;
+			userEditorCommand(command);
+			return;
 		}
-		if (command.eid == eid){
-			//エディタからの新たな編集コマンド
-			if (next==this) return; // singleton case
-			translator.transSendCmd(command);
-			sendEditorCommand(command);
-			return;
-		} else if (command.eid == REP.MERGE_EID.id){
+		if (command.eid == REP.MERGE_EID.id){
 			//マージコマンドが返ってきた
+			checkDouble(sentList);
 			if(translator.checkMergeConflict(command)){
 				//マージ中にエディタからの割り込みがあった場合
 				translator.getMergeAgain(this);
 			}
 			checkEndMerge();
+			checkDouble(sentList);
+			return;
 		} else if (command.eid == next.getEID()){
 			// 次のEditorで一周するコマンドが来た
-			// この方法、あんまり良くない...
 			if (next==this) return; // singleton case
 			// これは、distributed case では、うまくいかないので、送り先のforwarder で処理する。
-			if (next.isDirect()) {
-				REPCommand keep;
-				if (waitingRequired(command)) return;
-				keep = new REPCommand(command);
-				sentList.add(keep);
-				checkDouble(sentList);
+			if (next.isDirect()&&command.cmd==REP.SMCMD_QUIT_2) {
 				next.forwardedCommandManage(command);
-				// ((Editor) next).checkReturnedCommand(command);
-			} else
-				next.send(command);
-		} else {
-			//他のエディタからの編集コマンド
+				return;
+			}
+		} else if (command.eid == eid){ 
+			// 編集コマンドが一周して来た
 			if (waitingRequired(command)) return;
-			translator.transReceiveCmd(next,command);
-			if(command.cmd==REP.REPCMD_DELETE) {
-				// delete のundo用の文字列は、外に出す意味はない
-				command.string=null;
-			}
-			sendEditorCommand(command);
+			checkReturnedCommand(command);
+			checkDouble(sentList);
+			return;
 		}
+
+		//他のエディタからの編集コマンド
+		if (waitingRequired(command)) return;
+		translator.transReceiveCmd(next,command);
+		if(command.cmd==REP.REPCMD_DELETE) {
+			// delete のundo用の文字列は、外に出す意味はない
+			command.string=null;
+		}
+		sendEditorCommand(command);
+		return;
+	}
+
+	private void userEditorCommand(REPCommand command) {
+		//エディタからの新たな編集コマンド
+		if (next==this) return; // singleton case
+		translator.transSendCmd(command);
+		sendEditorCommand(command);
+		checkDouble(sentList);
 		return;
 	}
 	
@@ -103,22 +116,41 @@
 			}
 		}
 		assert(count==1);
+		if (true) return;
+		count = 0;
+		for(PacketSet c:waitingCommandInMerge) {
+			for(REPCommand g:sentList) { 
+				if (c.command.eid==g.eid&&c.command.seq==g.seq) {
+					count++;
+				}
+			}
+		}
+		assert(count==0);
 	}
 
 	private boolean waitingRequired(REPCommand command) {
 		if (hasWaitingCommand()) {
 			// We cannot do this operation before watingCommandQueue.
-			addWaitingCommand(new PacketSet(channel, this, command));
+			addWaitingCommand(new PacketSet(channel, this, new REPCommand(command)));
+			checkDouble(sentList);
 			return true;
 		} else if (isMerging()) { 
 			addWaitingCommand(new PacketSet(getChannel(), this, new REPCommand(command)));
+			checkDouble(sentList);
 			return true;
 		} 
+		checkDouble(sentList);
 		ServerMainLoop.logger.writeLog("Editor eid:"+eid+" no waiting");
 		return false;
 	}
 
 	public void addWaitingCommand(PacketSet set) {
+		if (preMergeCommand!=null) {
+			if (preMergeCommand.eid==set.command.eid
+					&& preMergeCommand.seq==set.command.seq) {
+				assert(false);
+			}
+		}
 		waitingCommandInMerge.add(set);
 	}
 	
@@ -162,6 +194,7 @@
 	private void startMerge(REPCommand command) {
 		preMergeCommand = new REPCommand(command);
 		preMergeCommand.string = "";
+		checkDouble(sentList);
 		// merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。
 		if (noMergeMode) {
 			endMerge();
@@ -175,6 +208,7 @@
 		// Session Manager 側で、このeditorへの他のeditorからの
 		// 入力を止めて、merge にそなえる。merge は、eidtor 側から
 		// ACKが来てから始まる。
+		checkDouble(sentList);
 		translator.startMerge(cmd);
 	}
 
@@ -251,6 +285,8 @@
 
 		case REPCMD_DELETE:
 		case REPCMD_INSERT:
+		case REPCMD_DELETE_USER:
+		case REPCMD_INSERT_USER:
 		case REPCMD_DELETE_ACK:
 		case REPCMD_INSERT_ACK:
 		case REPCMD_NOP:
@@ -325,7 +361,9 @@
 			return;
 		}
 		if (manager.sessionManage(this, command)) return;
+		checkDouble(sentList);
 		manage(command);
+		checkDouble(sentList);
 	}
 
 	@Override
@@ -343,28 +381,11 @@
 	 * it is forwarded here.
 	 */
 	public void forwardedCommandManage(REPCommand command) {
-		if (waitingRequired(command)) return;
 		if (command.cmd==REP.SMCMD_QUIT_2) {
 			// we have to wait next editor's finishing before sending this.
 			// this is odd, but the editor itself does not know it's merging
 			// state. Only this session manager knows it.
 			setQuit2(command);
-		} else if (command.eid==eid) {
-			// if we handle in editor.manage(), this editor cannot distinguish this
-			// and user input command from the editor.
-//			REPCommand keep;
-			switch(command.cmd) {
-			case REPCMD_INSERT:
-			case REPCMD_DELETE:
-//				keep = new REPCommand(command);
-//				sentList.add(keep);				
-//				ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
-//				checkDouble(sentList);
-			case REPCMD_INSERT_ACK:
-			case REPCMD_DELETE_ACK:
-				checkReturnedCommand(command);
-				return;
-			}
 		} 
 		send(command);
 	}
@@ -378,7 +399,7 @@
 		int count = waitingCommandInMerge.size();
 		if (count==0) return;
 		if (isMerging()) return;
-		while(count++>0) {
+		while(count-->0) {
 			PacketSet p = waitingCommandInMerge.remove(0);
 			try {
 				//					if (manager.sessionManage(e, p.command)) { // we don't need this
--- a/test/Text.java	Mon Nov 24 23:11:51 2008 +0900
+++ b/test/Text.java	Tue Nov 25 01:41:11 2008 +0900
@@ -48,10 +48,12 @@
 	}
 	
 	public String edit(REPCommand cmd){
-		if (cmd.cmd==REP.REPCMD_INSERT)        return insert(cmd.lineno, cmd.string);
-		//else if (cmd.cmd==REP.REPCMD_REPLACE)  return replace(cmd.lineno, cmd.string);
-		else if (cmd.cmd==REP.REPCMD_DELETE)   return delete(cmd.lineno);
-		//else assert false;
+		switch(cmd.cmd) {
+		case REPCMD_INSERT_USER:
+		case REPCMD_INSERT:   return insert(cmd.lineno, cmd.string);
+		case REPCMD_DELETE_USER:
+		case REPCMD_DELETE:   return delete(cmd.lineno);
+		}
 		return null;
 	}
 	
--- a/test/sematest/TestEditor.java	Mon Nov 24 23:11:51 2008 +0900
+++ b/test/sematest/TestEditor.java	Tue Nov 25 01:41:11 2008 +0900
@@ -43,7 +43,7 @@
 	private boolean hasInputLock=false;
 	private int port;
 	private REPSelector<REPCommand> selector;
-	private boolean syncEnable=false;
+	private boolean syncEnable=true;
 
 
 	public TestEditor(String name, String _host,int _port, boolean master){
@@ -61,14 +61,14 @@
 			this.master=true;
 			text = new Text(txts);
 			cmds.add(new REPCommand(REP.SMCMD_PUT,0,0,0,0,name+"-file"));
-			cmds.add(new REPCommand(REP.REPCMD_INSERT,0,0,0,0,"m0"));
-			cmds.add(new REPCommand(REP.REPCMD_DELETE,0,0,0,0,"m0"));
+			cmds.add(new REPCommand(REP.REPCMD_INSERT_USER,0,0,0,0,"m0"));
+			cmds.add(new REPCommand(REP.REPCMD_DELETE_USER,0,0,0,0,"m0"));
 			//cmds.add(new REPCommand(REP.SMCMD_QUIT,0,0,0,0,""));
 		} else {
 			text = new Text(new String[0]);
 			cmds.add(new REPCommand(REP.SMCMD_JOIN,0,0,0,0,name));
-			//cmds.add(new REPCommand(REP.REPCMD_INSERT,0,0,0,0,"c0"));
-			//cmds.add(new REPCommand(REP.REPCMD_DELETE,0,0,0,0,"c0"));
+			cmds.add(new REPCommand(REP.REPCMD_INSERT_USER,0,0,0,0,"c0"));
+			cmds.add(new REPCommand(REP.REPCMD_DELETE_USER,0,0,0,0,"c0"));
 		}
 	}
 	
@@ -152,8 +152,8 @@
 			syncCounter=0;
 		} else {
 			int i=syncCounter-1;
-			REPCommand del = new REPCommand(REP.REPCMD_DELETE,sid,eid,0,i, text.get(i));
-			REPCommand ins = new REPCommand(REP.REPCMD_INSERT,sid,eid,0,i, text.get(i));
+			REPCommand del = new REPCommand(REP.REPCMD_DELETE_USER,sid,eid,0,i, text.get(i));
+			REPCommand ins = new REPCommand(REP.REPCMD_INSERT_USER,sid,eid,0,i, text.get(i));
 			sendCommand(del);
 			sendCommand(ins);
 			syncCounter++;
@@ -167,11 +167,11 @@
 		REPCommand cmd = cmds.poll();
 		if (cmd!=null) {
 			switch(cmd.cmd) {
-			case REPCMD_INSERT:
+			case REPCMD_INSERT_USER:
 				text.insert(cmd.lineno, cmd.string);
 				sendCommand(cmd);
 				break;
-			case REPCMD_DELETE:
+			case REPCMD_DELETE_USER:
 				String del = text.delete(cmd.lineno);
 				cmd.setString(del);
 				sendCommand(cmd);