# HG changeset patch # User one # Date 1285161118 -32400 # Node ID 89a326696c544ffb7cfcdc42b63d991b513b296f # Parent ed97273477a0c2de715e18b095a698e95e4ee2ba mergeMark in sentList diff -r ed97273477a0 -r 89a326696c54 Todo --- 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 することに diff -r ed97273477a0 -r 89a326696c54 rep/handler/Editor.java --- 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 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()(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 n = new LinkedList(); - for(int i=0;i< sortedEditCmds.size()-1;i++) { - n.addLast(unMergedCmds.get(i)); - } sortedEditCmds = null; - unMergedCmds = n; + unMergedCmds = new LinkedList(); } /** * 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; }