# HG changeset patch # User one # Date 1287138469 -32400 # Node ID af2cf5d3769109aa1d4acc8b6cb3fb0554654f7c # Parent a7a17508ba35909f511fbd371140e4721266ae60 dead ended. diff -r a7a17508ba35 -r af2cf5d37691 Todo --- a/Todo Fri Oct 15 18:03:46 2010 +0900 +++ b/Todo Fri Oct 15 19:27:49 2010 +0900 @@ -2,6 +2,12 @@ でも単純ソートはうまくいかないはず。 +あ、そうか。このアルゴリズムだと、sentListがクリアされないものがいるね。 + +二巡目のack で消すのだろうが... + +あとsortの範囲の問題がやっぱりある。 + Tue Oct 12 10:37:38 JST 2010 やっぱり二周目に割り込んだコマンドが正しくsortされない。 @@ -46,6 +52,8 @@ 他コマンドのackは何もしない o merge 中の自コマンドは、確定させて処理(merge後に送信と同じ) +Ackが来たら確定で良い? + Editor3 Editor2 Editor1 c(eid=3) e(eid=2) a(eid=1) a(eid=1) c(eid=3) e(eid=2) @@ -87,16 +95,22 @@ a(eid=3) c(eid=1) c(eid=1)* e(eid=2) d(eid=3) <- このe,d がsortされない必要があるらしい d(eid=3) ca(eid=1)* a(eid=3)* - aa(eid=3)* d(eid=3) e(eid=2) - e(eid=2) aa(eid=3)* ca(eid=1)* + aa(eid=3)* d(eid=3) e(eid=2) <- a(eid=3)は確定、d(eid=3)は未確定 + e(eid=2) aa(eid=3)* ca(eid=1)* <- Editor1のe(eid=2)は、まだ未確定 e(eid=2)* d(eid=3)* da(eid=3)* ea(eid=2)* - ea(eid=2)* da(eid=3)* + ea(eid=2)* da(eid=3)* <- e(eid=2)を確定 [c,a,e,d] [c,a,e,d] [c,a,e,d] e(eid=2) は d(eid=3) を追い越す必要がある。 +他のエディタのコマンドが来た時に、優先順位でいきなりソート(merge)して良い。o +既に他のコマンドを送信した後に、自コマンドが来たら、その前までの自編集以外の編集まで確定。o +自コマンドのackで、まだ確定してない場合は確定。o +他コマンドのackは 二周目のackが来たら、そのコマンドまで確定 +merge 中の自コマンドは、確定させて処理(merge後に送信と同じ) + Editor1 Editor2 Editor3 c(eid=1) a(eid=3) a(eid=3) c(eid=1) diff -r a7a17508ba35 -r af2cf5d37691 rep/handler/Editor.java --- a/rep/handler/Editor.java Fri Oct 15 18:03:46 2010 +0900 +++ b/rep/handler/Editor.java Fri Oct 15 19:27:49 2010 +0900 @@ -37,7 +37,6 @@ public static boolean noMergeMode=false; static final boolean doOptimize = false; private LinkedList writeQueue = new LinkedList(); - static boolean slowMerge = false; public Editor(SessionManager manager,int editorNo){ // no translator case @@ -105,11 +104,6 @@ case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK: if (command.eid==eid) { - if (slowMerge) { - checkReturnedCommand(command); - checkQuit(); - return; - } // Second Phase が終わって同期が終了。 // SessionManager.logger.writeLog("Complete "+command); checkAck(command); @@ -140,17 +134,12 @@ } if (command.eid == eid){ // 編集コマンドが一周して来た - if (slowMerge) { - checkAck(command); - sendAck(command); - } else { checkReturnedCommand(command); - } return; } //他のエディタからの編集コマンド - unMergedCmds.addFirst(new REPCommand(command)); + transReceiveCmd(next, command); startMerge(command); return; default: @@ -158,13 +147,17 @@ } } + public void transReceiveCmd(REPnode next, REPCommand command) { + unMergedCmds.addFirst(new REPCommand(command)); + } + /** * エディタからの新たな編集コマンド * 既に他コマンドを受け取っていたら、そこまで確定 * @param command */ private void userEditorCommand(REPCommand command) { - trancateUnMerge(command); + truncateUnMergeUser(command); if (next==this) return; // singleton case transSendCmd(command); sendEditorCommand(command); @@ -270,9 +263,10 @@ void checkReturnedCommand(REPCommand command) { checkAck(command); if (command.eid==eid) { - trancateUnMerge(command); + truncateUnMergeOwn(command); sendAck(command); } else { + truncateUnMergeAck(command); next.send(command); } } @@ -350,37 +344,74 @@ private void endMerge() { REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,""); sendToEditor(mergeEnd); + sendEditorCommand(preMergeCommand); + preMergeCommand = null; } /** * 確定操作 * command がackならば、unMergeList にあるかどうかを調べる。 - * なければ、もう終わっているので何もしない。 + * なければ、もう終わっているので何もしない。あれば、そこまでtruncate * ack でなければ、自コマンドの直前までのunMergedListを削除 * @param command */ - private void trancateUnMerge(REPCommand command) { + private void truncateUnMergeUser(REPCommand command) { LinkedListu = new LinkedList(); + LinkedList s = new LinkedList(); + for(REPCommand c:unMergedCmds) { + if (c.eid==eid) { + u.addLast(c); + s.addLast(sentList.removeFirst()); + } else { + u = new LinkedList(); + s = new LinkedList(); + } + } + sentList = s; + unMergedCmds = u; + } + + private void truncateUnMergeOwn(REPCommand command) { + LinkedListu = new LinkedList(); + LinkedList s = new LinkedList(); if (command.cmd==REP.REPCMD_INSERT_ACK||command.cmd==REP.REPCMD_DELETE_ACK) { boolean flag=false; + int i = 0; for(REPCommand c:unMergedCmds) { if (c.sid==command.sid&&c.eid==command.eid&&c.seq==command.seq) flag = true; + if (flag) { + u.addLast(c); s.addLast(sentList.get(i)); + } + i++; } if (flag) { + sentList = s; unMergedCmds = u; } return; - } else { + } + } + private void truncateUnMergeAck(REPCommand command) { + LinkedListu = new LinkedList(); + LinkedList s = new LinkedList(); + if (command.cmd==REP.REPCMD_INSERT_ACK||command.cmd==REP.REPCMD_DELETE_ACK) { + boolean flag=false; + int i = 0; for(REPCommand c:unMergedCmds) { - if (c.eid==eid) { - u.addLast(c); - } else { - u = new LinkedList(); + if (c.sid==command.sid&&c.eid==command.eid&&c.seq==command.seq) + flag = true; + if (flag) { + u.addLast(c); s.addLast(sentList.get(i)); } + i++; } - unMergedCmds = u; - } + if (flag) { + sentList = s; + unMergedCmds = u; + } + return; + } } private void sendAck(REPCommand command) { @@ -404,6 +435,9 @@ quit_2 = null; return true; } + if (sentList.size()>0) { + ServerMainLoop.logger.writeLog("Editor"+eid+": waitQuit2 sentList = "+sentList); + } return false; } @@ -481,9 +515,7 @@ private boolean isMergeCommand(REPCommand command) { switch(command.cmd) { case REPCMD_INSERT: case REPCMD_DELETE: - return slowMerge?false:command.eid==eid; - case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK: - return slowMerge?true:command.eid!=eid; + return command.eid!=eid; } return false; } @@ -644,7 +676,7 @@ } public boolean checkMergeConflict(REPCommand command) { - unMergedCmds.addFirst(new REPCommand(command)); + transReceiveCmd(command); REPCommand prev = sentMergedList.getFirst(); if (prev.seq==command.seq) {