comparison rep/handler/Editor.java @ 483:c792a1ebc0ff

new merge (again...)
author one
date Sat, 16 Oct 2010 20:48:38 +0900
parents 200166a494e9
children 7420dea70dd7
comparison
equal deleted inserted replaced
482:200166a494e9 483:c792a1ebc0ff
150 case REPCMD_MERGE_MARK: 150 case REPCMD_MERGE_MARK:
151 if (command.eid == REP.MERGE_EID.id){ 151 if (command.eid == REP.MERGE_EID.id){
152 //マージコマンドが返ってきた 152 //マージコマンドが返ってきた
153 if(checkMergeConflict(command)){ 153 if(checkMergeConflict(command)){
154 //マージ中にエディタからの割り込みがあった場合 154 //マージ中にエディタからの割り込みがあった場合
155 getMergeAgain(this); 155 getMergeAgain();
156 } 156 }
157 checkEndMerge(); 157 checkEndMerge();
158 return; 158 return;
159 } 159 }
160 if (command.eid == eid){ 160 if (command.eid == eid){
168 return; 168 return;
169 } 169 }
170 170
171 //他のエディタからの編集コマンド 171 //他のエディタからの編集コマンド
172 transReceiveCmd(next,command); 172 transReceiveCmd(next,command);
173 173 if (mergeMode==MergeMode.Direct)
174 sendEditorCommand(command); 174 startMerge(command);
175 else
176 sendEditorCommand(command);
175 return; 177 return;
176 default: 178 default:
177 assert(false); 179 assert(false);
178 } 180 }
179 } 181 }
180 182
181 private void userEditorCommand(REPCommand command) { 183 private void userEditorCommand(REPCommand command) {
182 //エディタからの新たな編集コマンド 184 //エディタからの新たな編集コマンド
185 if (mergeMode==MergeMode.Direct)
186 truncateSentList(command);
183 if (next==this) return; // singleton case 187 if (next==this) return; // singleton case
184 transSendCmd(command); 188 transSendCmd(command);
185 sendEditorCommand(command); 189 sendEditorCommand(command);
186 return; 190 return;
187 } 191 }
207 // } 211 // }
208 // assert(count==0); 212 // assert(count==0);
209 // } 213 // }
210 214
211 /** 215 /**
216 * truncate sentList and unMergedCmds
217 */
218 private void truncateSentList(REPCommand command) {
219
220 }
221
222 /**
212 * Sending to Editor and waiting Queue 223 * Sending to Editor and waiting Queue
213 * +--------+ 224 * +--------+
214 * send() --> write() -> | Editor | -> handle() -> manager() 225 * send() --> write() -> | Editor | -> handle() -> manager()
215 * +--------+ 226 * +--------+
216 * waitingQueue 227 * waitingQueue
275 command.string=null; 286 command.string=null;
276 } 287 }
277 next.send(command); 288 next.send(command);
278 } 289 }
279 290
280 public List<REPCommand> getSentList() {
281 return sentList;
282 }
283
284 public void setSentList(LinkedList<REPCommand> list) {
285 sentList = list;
286 }
287
288 /** 291 /**
289 * 一周して来たcommandの処理。 292 * 一周して来たcommandの処理。
290 * 293 *
291 *   INSERT/DELETEを受け取った時に、sentListに登録 294 *   INSERT/DELETEを受け取った時に、sentListに登録
292 * INSERT_ACK/DELETE_ACKが来たら一周。そこで、Mergeする。 295 * INSERT_ACK/DELETE_ACKが来たら一周。そこで、Mergeする。
296 * 途中から参加した場合、自分が受けとってないcommandのACKが先に来ることが 299 * 途中から参加した場合、自分が受けとってないcommandのACKが先に来ることが
297 * ある。それは、無視して良い。 300 * ある。それは、無視して良い。
298 * @param command 301 * @param command
299 */ 302 */
300 void checkReturnedCommand(REPCommand command) { 303 void checkReturnedCommand(REPCommand command) {
304 if (mergeMode!=MergeMode.Direct)
305 startMerge(command);
306 }
307
308 void startMerge(REPCommand command) {
301 ServerMainLoop.logger.writeLog("Editor"+eid+": startMerge "+command); 309 ServerMainLoop.logger.writeLog("Editor"+eid+": startMerge "+command);
302 preMergeCommand = new REPCommand(command); 310 preMergeCommand = new REPCommand(command);
303 // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。 311 // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。
304 if (mergeMode==MergeMode.NoMerge) { 312 if (mergeMode==MergeMode.NoMerge) {
305 checkQuit(); 313 checkQuit();
313 merging = true; 321 merging = true;
314 // Session Manager 側で、このeditorへの他のeditorからの 322 // Session Manager 側で、このeditorへの他のeditorからの
315 // 入力を止めて、merge にそなえる。merge は、eidtor 側から 323 // 入力を止めて、merge にそなえる。merge は、eidtor 側から
316 // ACKが来てから始まる。 324 // ACKが来てから始まる。
317 } 325 }
318 326
319 /** 327 /**
320 * sentList と ack を見比べて、正しい順序で来たかどうかを調べる。途中参加したEditorの場合は、Ackは 328 * sentList と ack を見比べて、正しい順序で来たかどうかを調べる。途中参加したEditorの場合は、Ackは
321 * 無視して良い。 329 * 無視して良い。
322 * @param command 330 * @param command
323 * @return 331 * @return
366 if (quit_2!=null) checkQuit(); 374 if (quit_2!=null) checkQuit();
367 } 375 }
368 376
369 377
370 private void endMerge() { 378 private void endMerge() {
371 sortedEditCmds = null;
372 LinkedList<REPCommand>u = new LinkedList<REPCommand>();
373 boolean flag=true;
374 for(REPCommand command:unMergedCmds) {
375 if (command.cmd==REP.REPCMD_MERGE_MARK) {
376 flag = false;
377 }
378 if (flag) u.addLast(command);
379 }
380 unMergedCmds = u;
381
382 REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,""); 379 REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,"");
383 sendToEditor(mergeEnd); 380 sendToEditor(mergeEnd);
381 if (mergeMode==MergeMode.Direct) {
382 sendEditorCommand(preMergeCommand);
383 preMergeCommand = null;
384 return ;
385 }
386 sortedEditCmds = null;
387 truncateUnMergedCmds();
384 checkAck(preMergeCommand); 388 checkAck(preMergeCommand);
385 if (preMergeCommand.eid==eid) { 389 if (preMergeCommand.eid==eid) {
386 if (mergeMode==MergeMode.Early) { 390 if (mergeMode==MergeMode.Early) {
387 sendAck(preMergeCommand); 391 sendAck(preMergeCommand);
388 } 392 }
390 ServerMainLoop.logger.writeLog("Editor"+eid+": send preMergeCommand "+preMergeCommand); 394 ServerMainLoop.logger.writeLog("Editor"+eid+": send preMergeCommand "+preMergeCommand);
391 next.send(preMergeCommand); 395 next.send(preMergeCommand);
392 } 396 }
393 // sentList.clear(); 397 // sentList.clear();
394 preMergeCommand = null; 398 preMergeCommand = null;
399 }
400
401 public void truncateUnMergedCmds() {
402 LinkedList<REPCommand>u = new LinkedList<REPCommand>();
403 boolean flag=true;
404 for(REPCommand command:unMergedCmds) {
405 if (command.cmd==REP.REPCMD_MERGE_MARK) {
406 flag = false;
407 }
408 if (flag) u.addLast(command);
409 }
410 unMergedCmds = u;
395 } 411 }
396 412
397 private void sendAck(REPCommand command) { 413 private void sendAck(REPCommand command) {
398 REPCommand keep = new REPCommand(command); 414 REPCommand keep = new REPCommand(command);
399 // First Phase End, send ACK 415 // First Phase End, send ACK
439 455
440 case SMCMD_START_MERGE_ACK: 456 case SMCMD_START_MERGE_ACK:
441 { 457 {
442 // マージの処理と次のエディタへコマンドを送信する処理 458 // マージの処理と次のエディタへコマンドを送信する処理
443 mergeAck(); 459 mergeAck();
444 if (!merge(this, preMergeCommand)) { 460 if (!merge(preMergeCommand)) {
445 // nothing to do, send END_MERGE 461 // nothing to do, send END_MERGE
446 checkEndMerge(); 462 checkEndMerge();
447 } 463 }
448 break; 464 break;
449 } 465 }
568 * is returned. At this 584 * is returned. At this
569 * stage my writeQueue is empty, our editor is waiting for me. 585 * stage my writeQueue is empty, our editor is waiting for me.
570 * Start merge process. 586 * Start merge process.
571 * @param cmd 587 * @param cmd
572 */ 588 */
573 public boolean merge(Editor editor, REPCommand prev){ 589 public boolean merge(REPCommand prev){
574 logger.writeLog("beforeMerge"+eid+":"+unMergedCmds); 590 logger.writeLog("beforeMerge"+eid+":"+unMergedCmds);
575 LinkedList<REPCommand> output = new LinkedList<REPCommand>(); 591 LinkedList<REPCommand> output = new LinkedList<REPCommand>();
576 LinkedList<REPCommand> newSentList = new LinkedList<REPCommand>(); 592 LinkedList<REPCommand> newSentList = new LinkedList<REPCommand>();
577 // merge queue上にあるコマンドを全部undoコマンドするのと同時に 593 // merge queue上にあるコマンドを全部undoコマンドするのと同時に
578 // sort したコマンド列を生成する 594 // sort したコマンド列を生成する
579 for( REPCommand cmd0 : unMergedCmds) { 595 for( REPCommand cmd0 : unMergedCmds) {
580 output.addLast( createUndo(cmd0) ); 596 output.addLast( createUndo(cmd0) );
581 } 597 }
582 598
583 sortedEditCmds = new TreeSet<REPCommand>(new REPCommandComparator(1)); 599 sortedEditCmds = new TreeSet<REPCommand>(new REPCommandComparator(1));
584 logger.writeLog("sentList"+eid+":"+editor.getSentList()); 600 logger.writeLog("sentList"+eid+":"+sentList);
585 for( REPCommand cmd0 : editor.getSentList()) { 601 for( REPCommand cmd0 : sentList ) {
586 if (cmd0.cmd==REP.REPCMD_INSERT || cmd0.cmd==REP.REPCMD_DELETE) { 602 if (cmd0.cmd==REP.REPCMD_INSERT || cmd0.cmd==REP.REPCMD_DELETE) {
587 sortedEditCmds.add(cmd0); 603 sortedEditCmds.add(cmd0);
588 } 604 }
589 } 605 }
590 output.addAll(sortedEditCmds); 606 output.addAll(sortedEditCmds);
591 output.addLast(new REPCommand(REP.REPCMD_MERGE_MARK,0, editor.getSID(), REP.MERGE_EID.id, editor.seq(), "")); 607 output.addLast(new REPCommand(REP.REPCMD_MERGE_MARK,0,sid, REP.MERGE_EID.id, seq(), ""));
592 logger.writeLog("sortedMerge"+eid+":"+sortedEditCmds); 608 logger.writeLog("sortedMerge"+eid+":"+sortedEditCmds);
593 // unMerged command のdeleteのundo string は、この時点で使えない。 609 // unMerged command のdeleteのundo string は、この時点で使えない。
594 // Editor 側から送り返して来たものを使う必要がある。 610 // Editor 側から送り返して来たものを使う必要がある。
595 unMergedCmds.clear(); 611 unMergedCmds.clear();
612 sentList = newSentList;
596 logger.writeLog("outputMerge"+eid+":"+output); 613 logger.writeLog("outputMerge"+eid+":"+output);
597 editor.setSentList(newSentList); 614 return optimizedSend(this,output);
598 return optimizedSend(editor,output);
599 } 615 }
600 616
601 /** 617 /**
602 * Sent optimized merged command list 618 * Sent optimized merged command list
603 * @param editor 619 * @param editor
681 merge_mode=false; 697 merge_mode=false;
682 } 698 }
683 return mergeAgain; 699 return mergeAgain;
684 } 700 }
685 701
686 public void getMergeAgain(Editor editor) { 702 public void getMergeAgain() {
687 if (sentMergedList.size()>0) return; // wait for previous merge completion 703 if (sentMergedList.size()>0) return; // wait for previous merge completion
688 704
689 LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>(); 705 LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>();
690 for(REPCommand command : unMergedCmds) { 706 for(REPCommand command : unMergedCmds) {
691 if (command.cmd==REP.REPCMD_INSERT||command.cmd==REP.REPCMD_DELETE) 707 if (command.cmd==REP.REPCMD_INSERT||command.cmd==REP.REPCMD_DELETE)
692 returnCommand.add(createUndo(command)); 708 returnCommand.add(createUndo(command));
693 } 709 }
694 returnCommand.addAll(sortedEditCmds); 710 returnCommand.addAll(sortedEditCmds);
695 returnCommand.addLast(new REPCommand(REP.REPCMD_MERGE_MARK,0, editor.getSID(), REP.MERGE_EID.id, editor.seq(), "")); 711 returnCommand.addLast(new REPCommand(REP.REPCMD_MERGE_MARK,0, sid, REP.MERGE_EID.id, seq(), ""));
696 returnCommand.addAll(editor.getSentList()); 712 returnCommand.addAll(sentList);
697 unMergedCmds.clear(); 713 unMergedCmds.clear();
698 logger.writeLog("MergeAgain "+eid+" ret="+returnCommand.size()); 714 logger.writeLog("MergeAgain "+eid+" ret="+returnCommand.size());
699 mergeAgain = false; 715 mergeAgain = false;
700 optimizedSend(editor, returnCommand); 716 optimizedSend(this, returnCommand);
701 } 717 }
702 // 718 //
703 // public boolean isFinished() { 719 // public boolean isFinished() {
704 // if(unMergedCmds.size() > 0) return false; 720 // if(unMergedCmds.size() > 0) return false;
705 // if(sentMergedList.size() > 0) return false; 721 // if(sentMergedList.size() > 0) return false;