# HG changeset patch # User one # Date 1227544871 -32400 # Node ID 29f01a7ce71f979c61b8bb34693b7edb14c0e4a0 # Parent 19705f4b80155b920d19ea1c3825a2d28f1a1490 INSERT_USER,DELETE_USER to distinguish user input diff -r 19705f4b8015 -r 29f01a7ce71f Todo --- 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して diff -r 19705f4b8015 -r 29f01a7ce71f rep/PacketSet.java --- 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+")"; + } } diff -r 19705f4b8015 -r 29f01a7ce71f rep/REP.java --- 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), diff -r 19705f4b8015 -r 29f01a7ce71f rep/handler/Editor.java --- 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 diff -r 19705f4b8015 -r 29f01a7ce71f test/Text.java --- 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; } diff -r 19705f4b8015 -r 29f01a7ce71f test/sematest/TestEditor.java --- 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 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);