Mercurial > hg > RemoteEditor > REPSessionManager
comparison rep/handler/Editor.java @ 482:200166a494e9
mergeMode
author | one |
---|---|
date | Sat, 16 Oct 2010 20:24:11 +0900 |
parents | d2762d669617 |
children | c792a1ebc0ff |
comparison
equal
deleted
inserted
replaced
481:607f1dfe2b80 | 482:200166a494e9 |
---|---|
31 private TreeSet<REPCommand> sortedEditCmds; | 31 private TreeSet<REPCommand> sortedEditCmds; |
32 boolean mergeAgain; | 32 boolean mergeAgain; |
33 public REPLogger logger = SessionManager.logger; | 33 public REPLogger logger = SessionManager.logger; |
34 boolean merge_mode = false; | 34 boolean merge_mode = false; |
35 | 35 |
36 public enum MergeMode { | |
37 NoMerge, // no merge | |
38 Slow, // merge at Ack | |
39 Early, // merge at returned command and Ack | |
40 Direct // merge at incoming command | |
41 } | |
36 private boolean merging; | 42 private boolean merging; |
37 public static boolean noMergeMode=false; | |
38 static final boolean doOptimize = false; | 43 static final boolean doOptimize = false; |
39 private LinkedList<REPCommand> writeQueue = new LinkedList<REPCommand>(); | 44 private LinkedList<REPCommand> writeQueue = new LinkedList<REPCommand>(); |
40 static boolean slowMerge = true; | 45 static MergeMode mergeMode = MergeMode.Direct; |
41 | 46 |
42 public Editor(SessionManager manager,int editorNo){ | 47 public Editor(SessionManager manager,int editorNo){ |
43 // no translator case | 48 // no translator case |
44 super(manager, null); | 49 super(manager, null); |
45 } | 50 } |
64 * Merge Protocol | 69 * Merge Protocol |
65 (0) Editor へのコマンドは、ack 以外は直接 Editor へ送られてしまう。(next.send(cmd)) | 70 (0) Editor へのコマンドは、ack 以外は直接 Editor へ送られてしまう。(next.send(cmd)) |
66 Editor から返ってくるコマンドをtranslatorが処理する。 | 71 Editor から返ってくるコマンドをtranslatorが処理する。 |
67 (1) Editor CommandをSession Ring 上に流し、それが戻って来るまでに、他のEditorから | 72 (1) Editor CommandをSession Ring 上に流し、それが戻って来るまでに、他のEditorから |
68 受け取った Editor Command をキューに入れておく。 | 73 受け取った Editor Command をキューに入れておく。 |
74 sentList 外に送り出したEditor Command | |
75 unMergedList 接続されたEditorのundo list (reverse order) | |
76 MergingSentList Mergeするlist 。Mergeのやり直し用。 | |
77 Slow/Early | |
69 (2) 戻って来たタイミングで、キュー上のEditor Commandを、eid とCommandの | 78 (2) 戻って来たタイミングで、キュー上のEditor Commandを、eid とCommandの |
70 順序を基にソートする。(self merge) | 79 順序を基にソートする。(self merge (Early)) |
71 (3) 他のEditorにソートのタイミングを与えるために、Editor Command の | 80 (3) 他のEditorにソートのタイミングを与えるために、Editor Command の |
72 ack を、もう一周させる。 | 81 ack を、もう一周させる。 |
73 (4) 他のEditorのCommandを受け取ってから、ack が来るまでのCommandをキューに | 82 (4) 他のEditorのCommandを受け取ってから、ack が来るまでのCommandをキューに |
74 入れておき、ack が来たら、eid とCommandの順序を基にソートする。(other merge) | 83 入れておき、ack が来たら、eid とCommandの順序を基にソートする。(other merge (Slow)) |
84 Direct | |
85 (5) 他のEditor Command が来た時点で、すぐにmergeする | |
86 (6) 自分のEditor Command が来て、 | |
87 未確定の他のEditor Command があれば、それを確定(sentList/unMergedListから削除) | |
88 自分のEditor Command はsentListに追加 (unMergedListには既に入っている) | |
89 (7) Ackが来たら、そのEditor Command まで確定 | |
75 | 90 |
76 Editor には、ソートした編集結果になるように、それまで行なった編集をUndo | 91 Editor には、ソートした編集結果になるように、それまで行なった編集をUndo |
77 して、ソートした編集結果を適用する。Undo が無駄な動作をしないように最適化する。 | 92 して、ソートした編集結果を適用する。Undo が無駄な動作をしないように最適化する。 |
78 | 93 */ |
94 | |
95 /* | |
79 handle() | 96 handle() |
80 セッションの処理 | 97 セッションの処理 |
81 manage() | 98 manage() |
82 編集コマンドは translate() へ | 99 編集コマンドは translate() へ |
83 一周して来た編集コマンドのACKは廃棄 (merge queue から削除) | 100 一周して来た編集コマンドのACKは廃棄 (merge queue から削除) |
105 public void translate(REPCommand command){ | 122 public void translate(REPCommand command){ |
106 switch(command.cmd) { | 123 switch(command.cmd) { |
107 case REPCMD_INSERT_ACK: | 124 case REPCMD_INSERT_ACK: |
108 case REPCMD_DELETE_ACK: | 125 case REPCMD_DELETE_ACK: |
109 if (command.eid==eid) { | 126 if (command.eid==eid) { |
110 if (slowMerge) { | 127 if (mergeMode==MergeMode.Slow) { |
111 checkReturnedCommand(command); | 128 checkReturnedCommand(command); |
112 checkQuit(); | 129 checkQuit(); |
113 return; | 130 return; |
114 } | 131 } |
115 // Second Phase が終わって同期が終了。 | 132 // Second Phase が終わって同期が終了。 |
140 checkEndMerge(); | 157 checkEndMerge(); |
141 return; | 158 return; |
142 } | 159 } |
143 if (command.eid == eid){ | 160 if (command.eid == eid){ |
144 // 編集コマンドが一周して来た | 161 // 編集コマンドが一周して来た |
145 if (slowMerge) { | 162 if (mergeMode==MergeMode.Slow) { |
146 checkAck(command); | 163 checkAck(command); |
147 sendAck(command); | 164 sendAck(command); |
148 } else { | 165 } else { |
149 checkReturnedCommand(command); | 166 checkReturnedCommand(command); |
150 } | 167 } |
282 */ | 299 */ |
283 void checkReturnedCommand(REPCommand command) { | 300 void checkReturnedCommand(REPCommand command) { |
284 ServerMainLoop.logger.writeLog("Editor"+eid+": startMerge "+command); | 301 ServerMainLoop.logger.writeLog("Editor"+eid+": startMerge "+command); |
285 preMergeCommand = new REPCommand(command); | 302 preMergeCommand = new REPCommand(command); |
286 // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。 | 303 // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。 |
287 if (noMergeMode) { | 304 if (mergeMode==MergeMode.NoMerge) { |
288 checkQuit(); | 305 checkQuit(); |
289 endMerge(); | 306 endMerge(); |
290 return; | 307 return; |
291 } | 308 } |
292 // START_MERGE を送る | 309 // START_MERGE を送る |
364 | 381 |
365 REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,""); | 382 REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,""); |
366 sendToEditor(mergeEnd); | 383 sendToEditor(mergeEnd); |
367 checkAck(preMergeCommand); | 384 checkAck(preMergeCommand); |
368 if (preMergeCommand.eid==eid) { | 385 if (preMergeCommand.eid==eid) { |
369 if (!slowMerge) { | 386 if (mergeMode==MergeMode.Early) { |
370 sendAck(preMergeCommand); | 387 sendAck(preMergeCommand); |
371 } | 388 } |
372 } else { | 389 } else { |
373 ServerMainLoop.logger.writeLog("Editor"+eid+": send preMergeCommand "+preMergeCommand); | 390 ServerMainLoop.logger.writeLog("Editor"+eid+": send preMergeCommand "+preMergeCommand); |
374 next.send(preMergeCommand); | 391 next.send(preMergeCommand); |
473 | 490 |
474 | 491 |
475 private boolean isMergeCommand(REPCommand command) { | 492 private boolean isMergeCommand(REPCommand command) { |
476 switch(command.cmd) { | 493 switch(command.cmd) { |
477 case REPCMD_INSERT: case REPCMD_DELETE: | 494 case REPCMD_INSERT: case REPCMD_DELETE: |
478 return slowMerge?false:command.eid==eid; | 495 return mergeMode==MergeMode.Slow?false:command.eid==eid; |
479 case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK: | 496 case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK: |
480 return slowMerge?true:command.eid!=eid; | 497 return mergeMode==MergeMode.Slow?true:command.eid!=eid; |
481 } | 498 } |
482 return false; | 499 return false; |
483 } | 500 } |
484 | 501 |
485 public void sendToEditor(REPCommand command) { | 502 public void sendToEditor(REPCommand command) { |