# HG changeset patch # User one # Date 1287228251 -32400 # Node ID 200166a494e9d81d7fd00f38529b5099607e8c26 # Parent 607f1dfe2b808418c903c996b8cbe43343b40912 mergeMode diff -r 607f1dfe2b80 -r 200166a494e9 rep/handler/Editor.java --- a/rep/handler/Editor.java Fri Oct 15 19:47:53 2010 +0900 +++ b/rep/handler/Editor.java Sat Oct 16 20:24:11 2010 +0900 @@ -33,11 +33,16 @@ public REPLogger logger = SessionManager.logger; boolean merge_mode = false; + public enum MergeMode { + NoMerge, // no merge + Slow, // merge at Ack + Early, // merge at returned command and Ack + Direct // merge at incoming command + } private boolean merging; - public static boolean noMergeMode=false; static final boolean doOptimize = false; private LinkedList writeQueue = new LinkedList(); - static boolean slowMerge = true; + static MergeMode mergeMode = MergeMode.Direct; public Editor(SessionManager manager,int editorNo){ // no translator case @@ -66,16 +71,28 @@ Editor から返ってくるコマンドをtranslatorが処理する。 (1) Editor CommandをSession Ring 上に流し、それが戻って来るまでに、他のEditorから 受け取った Editor Command をキューに入れておく。 + sentList 外に送り出したEditor Command + unMergedList 接続されたEditorのundo list (reverse order) + MergingSentList Mergeするlist 。Mergeのやり直し用。 + Slow/Early (2) 戻って来たタイミングで、キュー上のEditor Commandを、eid とCommandの - 順序を基にソートする。(self merge) + 順序を基にソートする。(self merge (Early)) (3) 他のEditorにソートのタイミングを与えるために、Editor Command の ack を、もう一周させる。 (4) 他のEditorのCommandを受け取ってから、ack が来るまでのCommandをキューに - 入れておき、ack が来たら、eid とCommandの順序を基にソートする。(other merge) + 入れておき、ack が来たら、eid とCommandの順序を基にソートする。(other merge (Slow)) + Direct + (5) 他のEditor Command が来た時点で、すぐにmergeする + (6) 自分のEditor Command が来て、 + 未確定の他のEditor Command があれば、それを確定(sentList/unMergedListから削除) + 自分のEditor Command はsentListに追加 (unMergedListには既に入っている) + (7) Ackが来たら、そのEditor Command まで確定 Editor には、ソートした編集結果になるように、それまで行なった編集をUndo して、ソートした編集結果を適用する。Undo が無駄な動作をしないように最適化する。 - + */ + + /* handle() セッションの処理 manage() @@ -107,7 +124,7 @@ case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK: if (command.eid==eid) { - if (slowMerge) { + if (mergeMode==MergeMode.Slow) { checkReturnedCommand(command); checkQuit(); return; @@ -142,7 +159,7 @@ } if (command.eid == eid){ // 編集コマンドが一周して来た - if (slowMerge) { + if (mergeMode==MergeMode.Slow) { checkAck(command); sendAck(command); } else { @@ -284,7 +301,7 @@ ServerMainLoop.logger.writeLog("Editor"+eid+": startMerge "+command); preMergeCommand = new REPCommand(command); // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。 - if (noMergeMode) { + if (mergeMode==MergeMode.NoMerge) { checkQuit(); endMerge(); return; @@ -366,7 +383,7 @@ sendToEditor(mergeEnd); checkAck(preMergeCommand); if (preMergeCommand.eid==eid) { - if (!slowMerge) { + if (mergeMode==MergeMode.Early) { sendAck(preMergeCommand); } } else { @@ -475,9 +492,9 @@ private boolean isMergeCommand(REPCommand command) { switch(command.cmd) { case REPCMD_INSERT: case REPCMD_DELETE: - return slowMerge?false:command.eid==eid; + return mergeMode==MergeMode.Slow?false:command.eid==eid; case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK: - return slowMerge?true:command.eid!=eid; + return mergeMode==MergeMode.Slow?true:command.eid!=eid; } return false; }